@elaraai/e3-ui-components 1.0.56 → 1.0.58
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/components/DatasetPreview.d.ts +7 -0
- package/dist/components/DatasetPreview.d.ts.map +1 -1
- package/dist/components/PagedDatasetPreview.d.ts +20 -0
- package/dist/components/PagedDatasetPreview.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/debug.d.ts +13 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useDatasetPage.d.ts +47 -0
- package/dist/hooks/useDatasetPage.d.ts.map +1 -0
- package/dist/index.cjs +206 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +208 -4
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
|
@@ -13,5 +13,12 @@ export interface DatasetPreviewProps {
|
|
|
13
13
|
* this dataset path (for mutable inputs). Task outputs stay read-only. */
|
|
14
14
|
editable?: boolean;
|
|
15
15
|
}
|
|
16
|
+
/** Human-readable byte size, shared with the paged preview. */
|
|
17
|
+
export declare function formatSize(bytes: number): string;
|
|
18
|
+
/** Download trigger with its own in-flight state, shared with the paged preview. */
|
|
19
|
+
export declare function DownloadButton({ onClick, label }: {
|
|
20
|
+
onClick: () => void;
|
|
21
|
+
label?: string;
|
|
22
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
16
23
|
export declare const DatasetPreview: import('react').NamedExoticComponent<DatasetPreviewProps>;
|
|
17
24
|
//# sourceMappingURL=DatasetPreview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatasetPreview.d.ts","sourceRoot":"","sources":["../../src/components/DatasetPreview.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"DatasetPreview.d.ts","sourceRoot":"","sources":["../../src/components/DatasetPreview.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAkB7D,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mDAAmD;IACnD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;+EAC2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,2CAYzF;AAED,eAAO,MAAM,cAAc,2DAgIzB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RequestOptions } from '@elaraai/e3-api-client';
|
|
2
|
+
import { EastTypeValue } from '@elaraai/east';
|
|
3
|
+
export interface PagedDatasetPreviewProps {
|
|
4
|
+
apiUrl: string;
|
|
5
|
+
repo: string;
|
|
6
|
+
workspace: string;
|
|
7
|
+
/** Dotted path string, e.g. "inputs.rows". */
|
|
8
|
+
path: string;
|
|
9
|
+
/** The dataset's East type (an Array/Set/Dict root). */
|
|
10
|
+
type: EastTypeValue;
|
|
11
|
+
/** Content hash of the current value — resets pages when it changes. */
|
|
12
|
+
hash: string;
|
|
13
|
+
/** Stored blob size, shown alongside the totals. */
|
|
14
|
+
sizeBytes: number;
|
|
15
|
+
requestOptions?: RequestOptions;
|
|
16
|
+
/** Triggers a whole-value download (the existing download flow). */
|
|
17
|
+
onDownload: () => void | Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export declare const PagedDatasetPreview: import('react').NamedExoticComponent<PagedDatasetPreviewProps>;
|
|
20
|
+
//# sourceMappingURL=PagedDatasetPreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PagedDatasetPreview.d.ts","sourceRoot":"","sources":["../../src/components/PagedDatasetPreview.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAkD,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAenG,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,aAAa,CAAC;IACpB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,oEAAoE;IACpE,UAAU,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAkCD,eAAO,MAAM,mBAAmB,gEAkIgH,CAAC"}
|
|
@@ -8,6 +8,7 @@ export { TaskLogs, type TaskLogsProps } from './TaskLogs.js';
|
|
|
8
8
|
export { UITaskPreview, type UITaskPreviewProps } from './UITaskPreview.js';
|
|
9
9
|
export { DataTaskPreview, type DataTaskPreviewProps } from './DataTaskPreview.js';
|
|
10
10
|
export { DatasetPreview, type DatasetPreviewProps } from './DatasetPreview.js';
|
|
11
|
+
export { PagedDatasetPreview, type PagedDatasetPreviewProps } from './PagedDatasetPreview.js';
|
|
11
12
|
export { StatusDisplay, type StatusDisplayProps } from './StatusDisplay.js';
|
|
12
13
|
export { EastValueViewer, type EastValueViewerProps } from './EastValueViewer.js';
|
|
13
14
|
export { VirtualizedLogViewer, type VirtualizedLogViewerProps } from './VirtualizedLogViewer.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/debug.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Opt-in debug logging for the paged dataset preview (#497).
|
|
7
|
+
*
|
|
8
|
+
* Silent by default. Enable with `localStorage['e3-paging-debug'] = '1'`
|
|
9
|
+
* (any value except 'off') to trace page fetches, resets, and short-page
|
|
10
|
+
* clamps in the console — everything is prefixed `[e3-paging]`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function pagingDebug(...args: unknown[]): void;
|
|
13
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CASpD"}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -11,5 +11,6 @@ export * from './tasks.js';
|
|
|
11
11
|
export * from './executions.js';
|
|
12
12
|
export { useDatasetStatus, type DatasetStatus, type UseDatasetStatusOptions } from './useDatasetStatus.js';
|
|
13
13
|
export { useDatasetValue, useDatasetDownload, type DatasetValueResult, type UseDatasetValueOptions } from './useDatasetValue.js';
|
|
14
|
+
export { useDatasetPage, type DatasetPageResult, type UseDatasetPageOptions, type DatasetPageWindow } from './useDatasetPage.js';
|
|
14
15
|
export { useTaskDetails, getTaskKind, getTaskMetadata, type UseTaskDetailsOptions } from './useTaskDetails.js';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACjI,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACjI,OAAO,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACjI,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import { RequestOptions, DatasetPageWindow } from '@elaraai/e3-api-client';
|
|
3
|
+
import { EastTypeValue } from '@elaraai/east';
|
|
4
|
+
import { QueryOverrides } from './types.js';
|
|
5
|
+
export type { DatasetPageWindow } from '@elaraai/e3-api-client';
|
|
6
|
+
export interface UseDatasetPageOptions {
|
|
7
|
+
requestOptions?: RequestOptions;
|
|
8
|
+
queryOverrides?: QueryOverrides;
|
|
9
|
+
/** Set false to skip the fetch. Defaults to true. */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Content hash of the current dataset version — part of the query key so
|
|
13
|
+
* cached pages invalidate when the underlying data changes. The fetch is
|
|
14
|
+
* gated on it being non-null.
|
|
15
|
+
*/
|
|
16
|
+
hash?: string | null;
|
|
17
|
+
/** East type to decode pages against. Required. */
|
|
18
|
+
type: EastTypeValue;
|
|
19
|
+
/** The window to read: an element window or one writer segment. */
|
|
20
|
+
window: DatasetPageWindow;
|
|
21
|
+
}
|
|
22
|
+
export interface DatasetPageResult {
|
|
23
|
+
/** The decoded window — a value of the dataset's own type. */
|
|
24
|
+
decoded: unknown;
|
|
25
|
+
/** Total elements in the dataset (pairs for Dict datasets). */
|
|
26
|
+
totalElements: number;
|
|
27
|
+
/** Byte size of the whole stored blob. */
|
|
28
|
+
totalBytes: number;
|
|
29
|
+
/** Whether `totalElements` is exact (segment windows of Set/Dict
|
|
30
|
+
* datasets report an upper bound). */
|
|
31
|
+
totalExact: boolean;
|
|
32
|
+
/** Segments in the stored blob; 0 when the blob carries no index. */
|
|
33
|
+
segmentCount: number;
|
|
34
|
+
/** Global element offset of the window's first element. */
|
|
35
|
+
offset: number;
|
|
36
|
+
/** Elements actually in this page (the server may clamp the limit). */
|
|
37
|
+
count: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fetch + decode one window of a collection (Array/Set/Dict) dataset.
|
|
41
|
+
*
|
|
42
|
+
* Pages are keyed by content hash and window, and the previous page is held
|
|
43
|
+
* on screen while the next loads, so stepping through windows never flashes
|
|
44
|
+
* the loading state.
|
|
45
|
+
*/
|
|
46
|
+
export declare function useDatasetPage(apiUrl: string, repo: string, workspace: string | null, datasetPath: string | null, options: UseDatasetPageOptions): UseQueryResult<DatasetPageResult, Error>;
|
|
47
|
+
//# sourceMappingURL=useDatasetPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDatasetPage.d.ts","sourceRoot":"","sources":["../../src/hooks/useDatasetPage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAA8B,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAExF,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IAClC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,mDAAmD;IACnD,IAAI,EAAE,aAAa,CAAC;IACpB,mEAAmE;IACnE,MAAM,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAC9B,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB;2CACuC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,OAAO,EAAE,qBAAqB,GAC/B,cAAc,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAgC1C"}
|
package/dist/index.cjs
CHANGED
|
@@ -63857,6 +63857,35 @@ function useDatasetDownload(apiUrl, repo, workspace, datasetPath, requestOptions
|
|
|
63857
63857
|
URL.revokeObjectURL(url);
|
|
63858
63858
|
}, [apiUrl, repo, workspace, datasetPath, pathParts, reqOpts]);
|
|
63859
63859
|
}
|
|
63860
|
+
function useDatasetPage(apiUrl, repo, workspace, datasetPath, options2) {
|
|
63861
|
+
const { requestOptions, queryOverrides, enabled = true, hash: hash2, type, window: window3 } = options2;
|
|
63862
|
+
const reqOpts = requestOptions ?? { token: null };
|
|
63863
|
+
const pathParts = React.useMemo(
|
|
63864
|
+
() => (datasetPath == null ? void 0 : datasetPath.split(".").filter(Boolean).map((v3) => east.variant("field", v3))) ?? [],
|
|
63865
|
+
[datasetPath]
|
|
63866
|
+
);
|
|
63867
|
+
const windowKey = "segment" in window3 ? `s${window3.segment}` : `${window3.offset}+${window3.limit}`;
|
|
63868
|
+
return reactQuery.useQuery({
|
|
63869
|
+
queryKey: ["datasetPage", apiUrl, repo, workspace, datasetPath, hash2 ?? null, windowKey],
|
|
63870
|
+
queryFn: async () => {
|
|
63871
|
+
const pinned = hash2 != null ? { ...window3, hash: hash2 } : window3;
|
|
63872
|
+
const page = await e3ApiClient.datasetGetPage(apiUrl, repo, workspace, pathParts, pinned, reqOpts);
|
|
63873
|
+
const decoded = east.decodeBeast2For(type)(page.data);
|
|
63874
|
+
return {
|
|
63875
|
+
decoded,
|
|
63876
|
+
totalElements: page.totalElements,
|
|
63877
|
+
totalBytes: page.totalBytes,
|
|
63878
|
+
totalExact: page.totalExact,
|
|
63879
|
+
segmentCount: page.segmentCount,
|
|
63880
|
+
offset: page.offset,
|
|
63881
|
+
count: page.count
|
|
63882
|
+
};
|
|
63883
|
+
},
|
|
63884
|
+
enabled: enabled && !!workspace && !!datasetPath && hash2 != null,
|
|
63885
|
+
placeholderData: reactQuery.keepPreviousData,
|
|
63886
|
+
...queryOverrides
|
|
63887
|
+
});
|
|
63888
|
+
}
|
|
63860
63889
|
function useTaskDetails(apiUrl, repo, workspace, taskName, options2) {
|
|
63861
63890
|
const reqOpts = (options2 == null ? void 0 : options2.requestOptions) ?? { token: null };
|
|
63862
63891
|
return reactQuery.useQuery({
|
|
@@ -64000,6 +64029,158 @@ class ErrorBoundary extends React.Component {
|
|
|
64000
64029
|
return this.props.children;
|
|
64001
64030
|
}
|
|
64002
64031
|
}
|
|
64032
|
+
function pagingDebug(...args) {
|
|
64033
|
+
try {
|
|
64034
|
+
if (typeof localStorage === "undefined") return;
|
|
64035
|
+
const flag = localStorage.getItem("e3-paging-debug");
|
|
64036
|
+
if (flag === null || flag === "off") return;
|
|
64037
|
+
} catch {
|
|
64038
|
+
return;
|
|
64039
|
+
}
|
|
64040
|
+
console.info("[e3-paging]", ...args);
|
|
64041
|
+
}
|
|
64042
|
+
const PAGE_SIZE = 500;
|
|
64043
|
+
function pageRows(type, decoded, offset) {
|
|
64044
|
+
if (type.type === "Array") {
|
|
64045
|
+
const elemType2 = type.value;
|
|
64046
|
+
return decoded.map((el, i) => ({
|
|
64047
|
+
node: eastUi.ValueTree.materialize(elemType2, el),
|
|
64048
|
+
step: east.variant("index", BigInt(offset + i))
|
|
64049
|
+
}));
|
|
64050
|
+
}
|
|
64051
|
+
if (type.type === "Dict") {
|
|
64052
|
+
const { key: keyType, value: valueType } = type.value;
|
|
64053
|
+
const printKey = east.printFor(keyType);
|
|
64054
|
+
const stringKeys = keyType.type === "String";
|
|
64055
|
+
return Array.from(decoded.entries()).map(([k2, v3], i) => ({
|
|
64056
|
+
node: eastUi.ValueTree.materialize(valueType, v3),
|
|
64057
|
+
step: stringKeys ? east.variant("key", k2) : east.variant("index", BigInt(offset + i)),
|
|
64058
|
+
label: stringKeys ? k2 : printKey(k2)
|
|
64059
|
+
}));
|
|
64060
|
+
}
|
|
64061
|
+
const elemType = type.value;
|
|
64062
|
+
return Array.from(decoded.values()).map((el, i) => ({
|
|
64063
|
+
node: eastUi.ValueTree.materialize(elemType, el),
|
|
64064
|
+
step: east.variant("index", BigInt(offset + i))
|
|
64065
|
+
}));
|
|
64066
|
+
}
|
|
64067
|
+
function emptyOf(type) {
|
|
64068
|
+
return type.type === "Array" ? [] : type.type === "Dict" ? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Set();
|
|
64069
|
+
}
|
|
64070
|
+
const PagedDatasetPreview = React.memo(function PagedDatasetPreview2({
|
|
64071
|
+
apiUrl,
|
|
64072
|
+
repo,
|
|
64073
|
+
workspace,
|
|
64074
|
+
path: path2,
|
|
64075
|
+
type,
|
|
64076
|
+
hash: hash2,
|
|
64077
|
+
sizeBytes,
|
|
64078
|
+
requestOptions,
|
|
64079
|
+
onDownload
|
|
64080
|
+
}) {
|
|
64081
|
+
const queryClient = reactQuery.useQueryClient();
|
|
64082
|
+
const [pages, setPages] = React.useState(/* @__PURE__ */ new Map());
|
|
64083
|
+
const [totals, setTotals] = React.useState(null);
|
|
64084
|
+
const [loadingCount, setLoadingCount] = React.useState(0);
|
|
64085
|
+
const [error3, setError] = React.useState(null);
|
|
64086
|
+
const inflightRef = React.useRef(/* @__PURE__ */ new Set());
|
|
64087
|
+
React.useEffect(() => {
|
|
64088
|
+
pagingDebug(`reset (path=${path2}, hash=${hash2.slice(0, 8)})`);
|
|
64089
|
+
setPages(/* @__PURE__ */ new Map());
|
|
64090
|
+
setTotals(null);
|
|
64091
|
+
setError(null);
|
|
64092
|
+
inflightRef.current.clear();
|
|
64093
|
+
}, [path2, hash2]);
|
|
64094
|
+
const loadPage = React.useCallback((pageIdx) => {
|
|
64095
|
+
if (inflightRef.current.has(pageIdx)) return;
|
|
64096
|
+
inflightRef.current.add(pageIdx);
|
|
64097
|
+
setLoadingCount((n2) => n2 + 1);
|
|
64098
|
+
pagingDebug(`fetch p${pageIdx} (offset=${pageIdx * PAGE_SIZE}, limit=${PAGE_SIZE}, hash=${hash2.slice(0, 8)})`);
|
|
64099
|
+
const pathParts = path2.split(".").filter(Boolean).map((v3) => east.variant("field", v3));
|
|
64100
|
+
const reqOpts = requestOptions ?? { token: null };
|
|
64101
|
+
queryClient.fetchQuery({
|
|
64102
|
+
queryKey: ["datasetPage", apiUrl, repo, workspace, path2, hash2, `p${pageIdx}`],
|
|
64103
|
+
// Hash-pinned: the URL is a pure function of the bytes, so any
|
|
64104
|
+
// HTTP cache between here and the server can hold it immutably.
|
|
64105
|
+
queryFn: () => e3ApiClient.datasetGetPage(apiUrl, repo, workspace, pathParts, { offset: pageIdx * PAGE_SIZE, limit: PAGE_SIZE, hash: hash2 }, reqOpts),
|
|
64106
|
+
staleTime: Infinity
|
|
64107
|
+
// pages of one content hash are immutable
|
|
64108
|
+
}).then((page) => {
|
|
64109
|
+
const decoded = east.decodeBeast2For(type)(page.data);
|
|
64110
|
+
const rows = pageRows(type, decoded, page.offset);
|
|
64111
|
+
pagingDebug(
|
|
64112
|
+
`p${pageIdx} ok: count=${page.count} rows=${rows.length} offset=${page.offset} total=${page.totalElements} segs=${page.segmentCount}`,
|
|
64113
|
+
rows.length > 0 ? `first=${JSON.stringify(rows[0].label ?? "(derived)")}` : "(empty)"
|
|
64114
|
+
);
|
|
64115
|
+
if (page.count < PAGE_SIZE && page.offset + page.count < page.totalElements) {
|
|
64116
|
+
pagingDebug(`p${pageIdx} SHORT page: server clamped ${PAGE_SIZE} → ${page.count}`);
|
|
64117
|
+
}
|
|
64118
|
+
setTotals({ elements: page.totalElements, bytes: page.totalBytes });
|
|
64119
|
+
setPages((prev2) => new Map(prev2).set(pageIdx, rows));
|
|
64120
|
+
}).catch((err) => {
|
|
64121
|
+
pagingDebug(`p${pageIdx} FAILED:`, err);
|
|
64122
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
64123
|
+
}).finally(() => {
|
|
64124
|
+
inflightRef.current.delete(pageIdx);
|
|
64125
|
+
setLoadingCount((n2) => n2 - 1);
|
|
64126
|
+
});
|
|
64127
|
+
}, [queryClient, apiUrl, repo, workspace, path2, hash2, requestOptions, type]);
|
|
64128
|
+
React.useEffect(() => {
|
|
64129
|
+
if (totals === null && error3 === null) loadPage(0);
|
|
64130
|
+
}, [totals, error3, loadPage]);
|
|
64131
|
+
const onNeedRows = React.useCallback((startRow, endRow) => {
|
|
64132
|
+
const first2 = Math.max(0, Math.floor(startRow / PAGE_SIZE));
|
|
64133
|
+
const last2 = Math.max(first2, Math.ceil(endRow / PAGE_SIZE) - 1);
|
|
64134
|
+
const missing = [];
|
|
64135
|
+
for (let p2 = first2; p2 <= last2; p2++) {
|
|
64136
|
+
if (!pages.has(p2)) missing.push(p2);
|
|
64137
|
+
}
|
|
64138
|
+
pagingDebug(`need rows [${startRow}, ${endRow}) → pages ${first2}..${last2}, missing=[${missing.join(",")}], inflight=[${[...inflightRef.current].join(",")}]`);
|
|
64139
|
+
for (const p2 of missing) loadPage(p2);
|
|
64140
|
+
}, [pages, loadPage]);
|
|
64141
|
+
const treeValue = React.useMemo(() => ({
|
|
64142
|
+
root: eastUi.ValueTree.materialize(type, emptyOf(type)),
|
|
64143
|
+
onEdit: east.none,
|
|
64144
|
+
onInsert: east.none,
|
|
64145
|
+
onRemove: east.none,
|
|
64146
|
+
onTag: east.none,
|
|
64147
|
+
style: east.some({ height: east.some("100%"), maxHeight: east.none, openDepth: east.none, toolbar: east.some(true) })
|
|
64148
|
+
}), [type]);
|
|
64149
|
+
const paging = React.useMemo(() => totals === null ? null : {
|
|
64150
|
+
totalRows: totals.elements,
|
|
64151
|
+
pageSize: PAGE_SIZE,
|
|
64152
|
+
pages,
|
|
64153
|
+
onNeedRows
|
|
64154
|
+
}, [totals, pages, onNeedRows]);
|
|
64155
|
+
if (error3 !== null) {
|
|
64156
|
+
if (error3 instanceof e3ApiClient.ApiError && error3.code === "dataset_too_large") {
|
|
64157
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { height: "100%", direction: "column", align: "center", justify: "center", gap: 3, p: 6, children: [
|
|
64158
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "lg", color: "fg.warning", fontWeight: "bold", children: "Too large to page" }),
|
|
64159
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { color: "fg.muted", fontSize: "sm", textAlign: "center", maxW: "32rem", children: typeof error3.details === "string" ? error3.details : "This dataset cannot be paged server-side." }),
|
|
64160
|
+
/* @__PURE__ */ jsxRuntime.jsx(DownloadButton, { onClick: onDownload, label: "Download value" })
|
|
64161
|
+
] });
|
|
64162
|
+
}
|
|
64163
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "error", title: "Paged load failed", message: error3.message });
|
|
64164
|
+
}
|
|
64165
|
+
if (paging === null || totals === null) {
|
|
64166
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "loading", title: "Loading..." });
|
|
64167
|
+
}
|
|
64168
|
+
const itemNoun = type.type === "Dict" ? "entries" : "items";
|
|
64169
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { direction: "column", height: "100%", overflow: "hidden", children: [
|
|
64170
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { px: 4, py: 2, gap: 2, align: "center", flexShrink: 0, borderBottom: "1px solid", borderColor: "border.subtle", children: [
|
|
64171
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Text, { fontSize: "xs", color: "fg.muted", whiteSpace: "nowrap", children: [
|
|
64172
|
+
totals.elements.toLocaleString(),
|
|
64173
|
+
" ",
|
|
64174
|
+
itemNoun,
|
|
64175
|
+
" · ",
|
|
64176
|
+
formatSize(totals.bytes > 0 ? totals.bytes : sizeBytes)
|
|
64177
|
+
] }),
|
|
64178
|
+
loadingCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "xs", color: "fg.muted", children: "Loading…" }),
|
|
64179
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Flex, { flex: 1, justify: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(DownloadButton, { onClick: onDownload }) })
|
|
64180
|
+
] }),
|
|
64181
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { flex: 1, minHeight: 0, overflow: "hidden", children: /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraValueTree, { value: treeValue, storageKey: `${path2}:page`, paging }) })
|
|
64182
|
+
] });
|
|
64183
|
+
}, (prev2, next2) => prev2.path === next2.path && prev2.workspace === next2.workspace && prev2.hash === next2.hash && prev2.sizeBytes === next2.sizeBytes);
|
|
64003
64184
|
const DEFAULT_SIZE_LIMIT = 200 * 1024;
|
|
64004
64185
|
function formatSize(bytes) {
|
|
64005
64186
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -64072,7 +64253,7 @@ const DatasetPreview = React.memo(function DatasetPreview2({
|
|
|
64072
64253
|
onRemove: east.some((p2) => write(eastUi.ValueTree.applyEdit(type, decoded, p2, { kind: "remove" }))),
|
|
64073
64254
|
onTag: east.some((p2, tag) => write(eastUi.ValueTree.applyEdit(type, decoded, p2, { kind: "tag", tag })))
|
|
64074
64255
|
} : { onEdit: east.none, onInsert: east.none, onRemove: east.none, onTag: east.none };
|
|
64075
|
-
return { root: root2, ...wire, style: east.some({ height: east.some("100%"), maxHeight: east.none }) };
|
|
64256
|
+
return { root: root2, ...wire, style: east.some({ height: east.some("100%"), maxHeight: east.none, openDepth: east.none, toolbar: east.some(true) }) };
|
|
64076
64257
|
}, [type, decoded, editable, write]);
|
|
64077
64258
|
if (statusQuery.isLoading) return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "loading", title: "Loading..." });
|
|
64078
64259
|
if (statusQuery.error) {
|
|
@@ -64082,6 +64263,23 @@ const DatasetPreview = React.memo(function DatasetPreview2({
|
|
|
64082
64263
|
if (!status) return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "info", title: "No status" });
|
|
64083
64264
|
if (!hasValue) return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "info", title: "No data available", message: "Waiting for a value to be set" });
|
|
64084
64265
|
if (isOversized) {
|
|
64266
|
+
const pageable = type !== void 0 && (type.type === "Array" || type.type === "Set" || type.type === "Dict");
|
|
64267
|
+
if (pageable && workspace != null && path2 != null && status.hash != null) {
|
|
64268
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
64269
|
+
PagedDatasetPreview,
|
|
64270
|
+
{
|
|
64271
|
+
apiUrl,
|
|
64272
|
+
repo,
|
|
64273
|
+
workspace,
|
|
64274
|
+
path: path2,
|
|
64275
|
+
type,
|
|
64276
|
+
hash: status.hash,
|
|
64277
|
+
sizeBytes,
|
|
64278
|
+
...requestOptions != null && { requestOptions },
|
|
64279
|
+
onDownload: download
|
|
64280
|
+
}
|
|
64281
|
+
);
|
|
64282
|
+
}
|
|
64085
64283
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { height: "100%", direction: "column", align: "center", justify: "center", layerStyle: "banner.stale", borderRadius: "0", gap: 3, p: 6, children: [
|
|
64086
64284
|
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "lg", color: "fg.warning", fontWeight: "bold", children: "Value too large to display" }),
|
|
64087
64285
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Text, { color: "fg.muted", fontSize: "sm", children: [
|
|
@@ -64096,9 +64294,14 @@ const DatasetPreview = React.memo(function DatasetPreview2({
|
|
|
64096
64294
|
}
|
|
64097
64295
|
if (valueQuery.isLoading || !valueQuery.data) return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "loading", title: "Loading..." });
|
|
64098
64296
|
if (valueQuery.error) return /* @__PURE__ */ jsxRuntime.jsx(StatusDisplay, { variant: "error", title: "Decode failed", message: valueQuery.error.message });
|
|
64297
|
+
const count = type === void 0 || decoded === void 0 ? null : type.type === "Array" ? decoded.length : type.type === "Set" || type.type === "Dict" ? decoded.size : null;
|
|
64298
|
+
const countText = count === null ? "" : `${count.toLocaleString()} ${(type == null ? void 0 : type.type) === "Dict" ? "entries" : "items"} · `;
|
|
64099
64299
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { direction: "column", height: "100%", overflow: "hidden", children: [
|
|
64100
64300
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { px: 4, py: 2, justify: "flex-end", flexShrink: 0, borderBottom: "1px solid", borderColor: "border.subtle", children: [
|
|
64101
|
-
/* @__PURE__ */ jsxRuntime.
|
|
64301
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Text, { fontSize: "xs", color: "fg.muted", mr: 2, alignSelf: "center", children: [
|
|
64302
|
+
countText,
|
|
64303
|
+
formatSize(sizeBytes)
|
|
64304
|
+
] }),
|
|
64102
64305
|
/* @__PURE__ */ jsxRuntime.jsx(DownloadButton, { onClick: download })
|
|
64103
64306
|
] }),
|
|
64104
64307
|
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { flex: 1, minHeight: 0, overflow: "hidden", children: treeValue !== null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraValueTree, { value: treeValue, storageKey: path2 ?? "value" }) })
|
|
@@ -65172,6 +65375,7 @@ exports.useDatasetListAt = useDatasetListAt;
|
|
|
65172
65375
|
exports.useDatasetListRecursive = useDatasetListRecursive;
|
|
65173
65376
|
exports.useDatasetListRecursivePaths = useDatasetListRecursivePaths;
|
|
65174
65377
|
exports.useDatasetListWithStatus = useDatasetListWithStatus;
|
|
65378
|
+
exports.useDatasetPage = useDatasetPage;
|
|
65175
65379
|
exports.useDatasetSet = useDatasetSet;
|
|
65176
65380
|
exports.useDatasetStatus = useDatasetStatus;
|
|
65177
65381
|
exports.useDatasetValue = useDatasetValue;
|