juxscript 1.1.163 → 1.1.165

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
@@ -13,6 +13,7 @@ import { dialog } from './lib/components/dialog.js';
13
13
  import { divider } from './lib/components/divider.js';
14
14
  import { dropdown } from './lib/components/dropdown.js';
15
15
  import { dropdownMenu } from './lib/components/dropdown-menu.js';
16
+ import { dataframe } from './lib/components/dataframe.js';
16
17
  import { element } from './lib/components/element.js';
17
18
  import { fileupload } from './lib/components/fileupload.js';
18
19
  import { grid } from './lib/components/grid.js';
@@ -53,6 +54,7 @@ export { tabularDriver } from './lib/storage/TabularDriver.js';
53
54
  export { DataFrame } from './lib/storage/DataFrame.js';
54
55
  export { indexedDBDriver } from './lib/storage/IndexedDBDriver.js';
55
56
  export { fileStorage } from './lib/storage/FileStorage.js';
57
+ export { dataframe } from './lib/components/dataframe.js';
56
58
  import { VStack, vstack } from './lib/components/stack/VStack.js';
57
59
  import { HStack, hstack } from './lib/components/stack/HStack.js';
58
60
  import { ZStack, zstack } from './lib/components/stack/ZStack.js';
@@ -73,6 +75,7 @@ export declare const jux: {
73
75
  code: typeof code;
74
76
  container: typeof container;
75
77
  data: typeof data;
78
+ dataframe: typeof dataframe;
76
79
  datepicker: typeof datepicker;
77
80
  dialog: typeof dialog;
78
81
  divider: typeof divider;
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -13,6 +13,7 @@ import { dialog } from './lib/components/dialog.js';
13
13
  import { divider } from './lib/components/divider.js';
14
14
  import { dropdown } from './lib/components/dropdown.js';
15
15
  import { dropdownMenu } from './lib/components/dropdown-menu.js';
16
+ import { dataframe } from './lib/components/dataframe.js';
16
17
  import { element } from './lib/components/element.js';
17
18
  import { fileupload } from './lib/components/fileupload.js';
18
19
  import { grid } from './lib/components/grid.js';
@@ -56,6 +57,7 @@ export { tabularDriver } from './lib/storage/TabularDriver.js';
56
57
  export { DataFrame } from './lib/storage/DataFrame.js';
57
58
  export { indexedDBDriver } from './lib/storage/IndexedDBDriver.js';
58
59
  export { fileStorage } from './lib/storage/FileStorage.js';
60
+ export { dataframe } from './lib/components/dataframe.js';
59
61
  // Import Stack components (already added earlier)
60
62
  import { VStack, vstack } from './lib/components/stack/VStack.js';
61
63
  import { HStack, hstack } from './lib/components/stack/HStack.js';
@@ -79,6 +81,7 @@ export const jux = {
79
81
  code,
80
82
  container,
81
83
  data,
84
+ dataframe,
82
85
  datepicker,
83
86
  dialog,
84
87
  divider,
@@ -0,0 +1,110 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ import { DataFrame } from '../storage/DataFrame.js';
3
+ import { TabularDriver } from '../storage/TabularDriver.js';
4
+ import { FileUpload } from './fileupload.js';
5
+ import { Table } from './table.js';
6
+ export interface DataFrameOptions {
7
+ dbName?: string;
8
+ storeName?: string;
9
+ striped?: boolean;
10
+ hoverable?: boolean;
11
+ sortable?: boolean;
12
+ filterable?: boolean;
13
+ paginated?: boolean;
14
+ rowsPerPage?: number;
15
+ style?: string;
16
+ class?: string;
17
+ }
18
+ type DataFrameState = BaseState & {
19
+ loaded: boolean;
20
+ sourceName: string;
21
+ rowCount: number;
22
+ colCount: number;
23
+ };
24
+ export declare class DataFrameComponent extends BaseComponent<DataFrameState> {
25
+ private _df;
26
+ private _driver;
27
+ private _table;
28
+ private _tableOptions;
29
+ private _uploadRef;
30
+ private _storageKey;
31
+ private _pendingSource;
32
+ constructor(id: string, options?: DataFrameOptions);
33
+ protected getTriggerEvents(): readonly string[];
34
+ protected getCallbackEvents(): readonly string[];
35
+ /**
36
+ * Load from IndexedDB by storage key
37
+ */
38
+ fromStorage(key: string): this;
39
+ /**
40
+ * Load from a FileUpload component — auto-wires change event
41
+ */
42
+ fromUpload(upload: FileUpload): this;
43
+ /**
44
+ * Load from raw data — array of objects or Record<string, any[]>
45
+ */
46
+ fromData(data: Record<string, any>[] | Record<string, any[]>): this;
47
+ /**
48
+ * Apply a transform to the current DataFrame and update the table
49
+ */
50
+ apply(fn: (df: DataFrame) => DataFrame): this;
51
+ /**
52
+ * Filter rows
53
+ */
54
+ filter(predicate: (row: Record<string, any>, index: number) => boolean): this;
55
+ /**
56
+ * Select columns
57
+ */
58
+ select(...cols: string[]): this;
59
+ /**
60
+ * Sort by column
61
+ */
62
+ sort(col: string, descending?: boolean): this;
63
+ /**
64
+ * Show first N rows
65
+ */
66
+ head(n?: number): this;
67
+ /**
68
+ * Show last N rows
69
+ */
70
+ tail(n?: number): this;
71
+ /**
72
+ * Add a computed column
73
+ */
74
+ withColumn(name: string, fn: (row: Record<string, any>, index: number) => any): this;
75
+ /**
76
+ * Where clause
77
+ */
78
+ where(col: string, op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'contains' | 'startsWith' | 'endsWith', value: any): this;
79
+ /** Get the underlying DataFrame */
80
+ get df(): DataFrame | null;
81
+ /** Get the underlying TabularDriver */
82
+ get driver(): TabularDriver;
83
+ /** Get the internal Table component */
84
+ get table(): Table | null;
85
+ /** Get describe() stats */
86
+ describe(): Record<string, any> | null;
87
+ /** Export to CSV string */
88
+ toCSV(delimiter?: string): string;
89
+ /** Export to row objects */
90
+ toRows(): Record<string, any>[];
91
+ /** Get shape */
92
+ get shape(): [number, number];
93
+ /** Get column names */
94
+ get columns(): string[];
95
+ /** Save current DataFrame to IndexedDB */
96
+ save(key?: string): Promise<string | null>;
97
+ striped(v: boolean): this;
98
+ hoverable(v: boolean): this;
99
+ sortable(v: boolean): this;
100
+ filterable(v: boolean): this;
101
+ paginated(v: boolean): this;
102
+ rowsPerPage(v: number): this;
103
+ private _setDataFrame;
104
+ private _updateTable;
105
+ update(prop: string, value: any): void;
106
+ render(targetId?: string | HTMLElement | BaseComponent<any>): this;
107
+ }
108
+ export declare function dataframe(id: string, options?: DataFrameOptions): DataFrameComponent;
109
+ export {};
110
+ //# sourceMappingURL=dataframe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataframe.d.ts","sourceRoot":"","sources":["dataframe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,292 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { DataFrame } from '../storage/DataFrame.js';
3
+ import { TabularDriver } from '../storage/TabularDriver.js';
4
+ import { Table } from './table.js';
5
+ const TRIGGER_EVENTS = [];
6
+ const CALLBACK_EVENTS = ['load', 'error', 'transform'];
7
+ export class DataFrameComponent extends BaseComponent {
8
+ constructor(id, options = {}) {
9
+ super(id, {
10
+ visible: true,
11
+ disabled: false,
12
+ loading: false,
13
+ style: options.style ?? '',
14
+ class: options.class ?? '',
15
+ loaded: false,
16
+ sourceName: '',
17
+ rowCount: 0,
18
+ colCount: 0
19
+ });
20
+ this._df = null;
21
+ this._table = null;
22
+ this._uploadRef = null;
23
+ this._storageKey = null;
24
+ this._pendingSource = null;
25
+ this._driver = new TabularDriver(options.dbName ?? 'jux-dataframes', options.storeName ?? 'frames');
26
+ this._tableOptions = {
27
+ striped: options.striped ?? true,
28
+ hoverable: options.hoverable ?? true,
29
+ sortable: options.sortable ?? true,
30
+ filterable: options.filterable ?? true,
31
+ paginated: options.paginated ?? true,
32
+ rowsPerPage: options.rowsPerPage ?? 25
33
+ };
34
+ }
35
+ getTriggerEvents() { return TRIGGER_EVENTS; }
36
+ getCallbackEvents() { return CALLBACK_EVENTS; }
37
+ /* ═══════════════════════════════════════════════════
38
+ * DATA SOURCES
39
+ * ═══════════════════════════════════════════════════ */
40
+ /**
41
+ * Load from IndexedDB by storage key
42
+ */
43
+ fromStorage(key) {
44
+ this._storageKey = key;
45
+ this._pendingSource = async () => {
46
+ this.state.loading = true;
47
+ try {
48
+ let df = await this._driver.loadByName(key);
49
+ if (!df) {
50
+ this._triggerCallback('error', 'No table found with key: ' + key, null, this);
51
+ this.state.loading = false;
52
+ return;
53
+ }
54
+ this._setDataFrame(df, 'storage: ' + key);
55
+ }
56
+ catch (err) {
57
+ this._triggerCallback('error', err.message, null, this);
58
+ this.state.loading = false;
59
+ }
60
+ };
61
+ return this;
62
+ }
63
+ /**
64
+ * Load from a FileUpload component — auto-wires change event
65
+ */
66
+ fromUpload(upload) {
67
+ this._uploadRef = upload;
68
+ this._pendingSource = async () => {
69
+ // Wire upload's change event to parse incoming files
70
+ upload.bind('change', async (files) => {
71
+ if (!files || files.length === 0)
72
+ return;
73
+ const file = files[0];
74
+ this.state.loading = true;
75
+ try {
76
+ const df = await this._driver.streamFile(file);
77
+ // Auto-persist to IndexedDB
78
+ await this._driver.store(file.name, df, { source: file.name });
79
+ this._setDataFrame(df, 'upload: ' + file.name);
80
+ }
81
+ catch (err) {
82
+ this._triggerCallback('error', err.message, null, this);
83
+ this.state.loading = false;
84
+ }
85
+ });
86
+ };
87
+ return this;
88
+ }
89
+ /**
90
+ * Load from raw data — array of objects or Record<string, any[]>
91
+ */
92
+ fromData(data) {
93
+ this._pendingSource = async () => {
94
+ this.state.loading = true;
95
+ try {
96
+ const df = new DataFrame(data);
97
+ this._setDataFrame(df, 'inline data');
98
+ }
99
+ catch (err) {
100
+ this._triggerCallback('error', err.message, null, this);
101
+ this.state.loading = false;
102
+ }
103
+ };
104
+ return this;
105
+ }
106
+ /* ═══════════════════════════════════════════════════
107
+ * TRANSFORM API (returns new DataFrameComponent view)
108
+ * ═══════════════════════════════════════════════════ */
109
+ /**
110
+ * Apply a transform to the current DataFrame and update the table
111
+ */
112
+ apply(fn) {
113
+ if (!this._df)
114
+ return this;
115
+ const result = fn(this._df);
116
+ this._setDataFrame(result, this.state.sourceName + ' (transformed)');
117
+ this._triggerCallback('transform', result, null, this);
118
+ return this;
119
+ }
120
+ /**
121
+ * Filter rows
122
+ */
123
+ filter(predicate) {
124
+ return this.apply(df => df.filter(predicate));
125
+ }
126
+ /**
127
+ * Select columns
128
+ */
129
+ select(...cols) {
130
+ return this.apply(df => df.select(...cols));
131
+ }
132
+ /**
133
+ * Sort by column
134
+ */
135
+ sort(col, descending) {
136
+ return this.apply(df => df.sort(col, descending));
137
+ }
138
+ /**
139
+ * Show first N rows
140
+ */
141
+ head(n = 5) {
142
+ return this.apply(df => df.head(n));
143
+ }
144
+ /**
145
+ * Show last N rows
146
+ */
147
+ tail(n = 5) {
148
+ return this.apply(df => df.tail(n));
149
+ }
150
+ /**
151
+ * Add a computed column
152
+ */
153
+ withColumn(name, fn) {
154
+ return this.apply(df => df.withColumn(name, fn));
155
+ }
156
+ /**
157
+ * Where clause
158
+ */
159
+ where(col, op, value) {
160
+ return this.apply(df => df.where(col, op, value));
161
+ }
162
+ /* ═══════════════════════════════════════════════════
163
+ * ACCESSORS
164
+ * ═══════════════════════════════════════════════════ */
165
+ /** Get the underlying DataFrame */
166
+ get df() { return this._df; }
167
+ /** Get the underlying TabularDriver */
168
+ get driver() { return this._driver; }
169
+ /** Get the internal Table component */
170
+ get table() { return this._table; }
171
+ /** Get describe() stats */
172
+ describe() {
173
+ return this._df?.describe() ?? null;
174
+ }
175
+ /** Export to CSV string */
176
+ toCSV(delimiter) {
177
+ return this._df?.toCSV(delimiter) ?? '';
178
+ }
179
+ /** Export to row objects */
180
+ toRows() {
181
+ return this._df?.toRows() ?? [];
182
+ }
183
+ /** Get shape */
184
+ get shape() {
185
+ return this._df?.shape ?? [0, 0];
186
+ }
187
+ /** Get column names */
188
+ get columns() {
189
+ return this._df?.columns ?? [];
190
+ }
191
+ /** Save current DataFrame to IndexedDB */
192
+ async save(key) {
193
+ if (!this._df)
194
+ return null;
195
+ const name = key ?? this._storageKey ?? this._id;
196
+ return this._driver.store(name, this._df);
197
+ }
198
+ /* ═══════════════════════════════════════════════════
199
+ * TABLE OPTIONS (fluent, pre-render)
200
+ * ═══════════════════════════════════════════════════ */
201
+ striped(v) { this._tableOptions.striped = v; return this; }
202
+ hoverable(v) { this._tableOptions.hoverable = v; return this; }
203
+ sortable(v) { this._tableOptions.sortable = v; return this; }
204
+ filterable(v) { this._tableOptions.filterable = v; return this; }
205
+ paginated(v) { this._tableOptions.paginated = v; return this; }
206
+ rowsPerPage(v) { this._tableOptions.rowsPerPage = v; return this; }
207
+ /* ═══════════════════════════════════════════════════
208
+ * INTERNAL
209
+ * ═══════════════════════════════════════════════════ */
210
+ _setDataFrame(df, sourceName) {
211
+ this._df = df;
212
+ this.state.loaded = true;
213
+ this.state.loading = false;
214
+ this.state.sourceName = sourceName;
215
+ this.state.rowCount = df.height;
216
+ this.state.colCount = df.width;
217
+ // Clean __EMPTY columns from xlsx artifacts
218
+ const cleanCols = df.columns.filter(c => !c.startsWith('__EMPTY'));
219
+ if (cleanCols.length < df.columns.length) {
220
+ this._df = df.select(...cleanCols);
221
+ }
222
+ this._updateTable();
223
+ this._triggerCallback('load', this._df, null, this);
224
+ }
225
+ _updateTable() {
226
+ if (!this._table || !this._df)
227
+ return;
228
+ this._table.columns(this._df.columns).rows(this._df.toRows());
229
+ }
230
+ update(prop, value) { }
231
+ /* ═══════════════════════════════════════════════════
232
+ * RENDER
233
+ * ═══════════════════════════════════════════════════ */
234
+ render(targetId) {
235
+ const container = this._setupContainer(targetId);
236
+ const { style, class: className } = this.state;
237
+ const wrapper = document.createElement('div');
238
+ wrapper.className = 'jux-dataframe';
239
+ wrapper.id = this._id;
240
+ if (className)
241
+ wrapper.className += ` ${className}`;
242
+ if (style)
243
+ wrapper.setAttribute('style', style);
244
+ // Status bar
245
+ const statusBar = document.createElement('div');
246
+ statusBar.className = 'jux-dataframe-status';
247
+ statusBar.id = `${this._id}-status`;
248
+ statusBar.style.cssText = 'font-size:13px;color:#888;margin-bottom:8px;';
249
+ statusBar.textContent = 'No data loaded.';
250
+ wrapper.appendChild(statusBar);
251
+ container.appendChild(wrapper);
252
+ // Create internal table
253
+ this._table = new Table(`${this._id}-table`, {
254
+ striped: this._tableOptions.striped,
255
+ hoverable: this._tableOptions.hoverable,
256
+ sortable: this._tableOptions.sortable,
257
+ filterable: this._tableOptions.filterable,
258
+ paginated: this._tableOptions.paginated,
259
+ rowsPerPage: this._tableOptions.rowsPerPage
260
+ });
261
+ this._table.render(wrapper);
262
+ // Watch state for status updates
263
+ const origUpdate = this.update.bind(this);
264
+ this.update = (prop, value) => {
265
+ origUpdate(prop, value);
266
+ if (prop === 'loaded' || prop === 'loading' || prop === 'rowCount' || prop === 'colCount' || prop === 'sourceName') {
267
+ const el = document.getElementById(`${this._id}-status`);
268
+ if (el) {
269
+ if (this.state.loading) {
270
+ el.textContent = '⏳ Loading...';
271
+ }
272
+ else if (this.state.loaded) {
273
+ el.textContent = `✅ ${this.state.sourceName} — ${this.state.rowCount} rows × ${this.state.colCount} cols`;
274
+ }
275
+ else {
276
+ el.textContent = 'No data loaded.';
277
+ }
278
+ }
279
+ }
280
+ };
281
+ // Execute pending data source
282
+ if (this._pendingSource) {
283
+ this._pendingSource();
284
+ this._pendingSource = null;
285
+ }
286
+ this._wireStandardEvents(wrapper);
287
+ return this;
288
+ }
289
+ }
290
+ export function dataframe(id, options = {}) {
291
+ return new DataFrameComponent(id, options);
292
+ }
@@ -0,0 +1,363 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ import { DataFrame } from '../storage/DataFrame.js';
3
+ import { TabularDriver } from '../storage/TabularDriver.js';
4
+ import { FileUpload } from './fileupload.js';
5
+ import { Table } from './table.js';
6
+
7
+ const TRIGGER_EVENTS = [] as const;
8
+ const CALLBACK_EVENTS = ['load', 'error', 'transform'] as const;
9
+
10
+ export interface DataFrameOptions {
11
+ dbName?: string;
12
+ storeName?: string;
13
+ striped?: boolean;
14
+ hoverable?: boolean;
15
+ sortable?: boolean;
16
+ filterable?: boolean;
17
+ paginated?: boolean;
18
+ rowsPerPage?: number;
19
+ style?: string;
20
+ class?: string;
21
+ }
22
+
23
+ type DataFrameState = BaseState & {
24
+ loaded: boolean;
25
+ sourceName: string;
26
+ rowCount: number;
27
+ colCount: number;
28
+ };
29
+
30
+ export class DataFrameComponent extends BaseComponent<DataFrameState> {
31
+ private _df: DataFrame | null = null;
32
+ private _driver: TabularDriver;
33
+ private _table: Table | null = null;
34
+ private _tableOptions: {
35
+ striped: boolean;
36
+ hoverable: boolean;
37
+ sortable: boolean;
38
+ filterable: boolean;
39
+ paginated: boolean;
40
+ rowsPerPage: number;
41
+ };
42
+ private _uploadRef: FileUpload | null = null;
43
+ private _storageKey: string | null = null;
44
+ private _pendingSource: (() => Promise<void>) | null = null;
45
+
46
+ constructor(id: string, options: DataFrameOptions = {}) {
47
+ super(id, {
48
+ visible: true,
49
+ disabled: false,
50
+ loading: false,
51
+ style: options.style ?? '',
52
+ class: options.class ?? '',
53
+ loaded: false,
54
+ sourceName: '',
55
+ rowCount: 0,
56
+ colCount: 0
57
+ });
58
+
59
+ this._driver = new TabularDriver(
60
+ options.dbName ?? 'jux-dataframes',
61
+ options.storeName ?? 'frames'
62
+ );
63
+
64
+ this._tableOptions = {
65
+ striped: options.striped ?? true,
66
+ hoverable: options.hoverable ?? true,
67
+ sortable: options.sortable ?? true,
68
+ filterable: options.filterable ?? true,
69
+ paginated: options.paginated ?? true,
70
+ rowsPerPage: options.rowsPerPage ?? 25
71
+ };
72
+ }
73
+
74
+ protected getTriggerEvents(): readonly string[] { return TRIGGER_EVENTS; }
75
+ protected getCallbackEvents(): readonly string[] { return CALLBACK_EVENTS; }
76
+
77
+ /* ═══════════════════════════════════════════════════
78
+ * DATA SOURCES
79
+ * ═══════════════════════════════════════════════════ */
80
+
81
+ /**
82
+ * Load from IndexedDB by storage key
83
+ */
84
+ fromStorage(key: string): this {
85
+ this._storageKey = key;
86
+ this._pendingSource = async () => {
87
+ this.state.loading = true;
88
+ try {
89
+ let df = await this._driver.loadByName(key);
90
+ if (!df) {
91
+ this._triggerCallback('error', 'No table found with key: ' + key, null, this);
92
+ this.state.loading = false;
93
+ return;
94
+ }
95
+ this._setDataFrame(df, 'storage: ' + key);
96
+ } catch (err: any) {
97
+ this._triggerCallback('error', err.message, null, this);
98
+ this.state.loading = false;
99
+ }
100
+ };
101
+ return this;
102
+ }
103
+
104
+ /**
105
+ * Load from a FileUpload component — auto-wires change event
106
+ */
107
+ fromUpload(upload: FileUpload): this {
108
+ this._uploadRef = upload;
109
+ this._pendingSource = async () => {
110
+ // Wire upload's change event to parse incoming files
111
+ upload.bind('change', async (files: File[]) => {
112
+ if (!files || files.length === 0) return;
113
+ const file = files[0];
114
+ this.state.loading = true;
115
+
116
+ try {
117
+ const df = await this._driver.streamFile(file);
118
+ // Auto-persist to IndexedDB
119
+ await this._driver.store(file.name, df, { source: file.name });
120
+ this._setDataFrame(df, 'upload: ' + file.name);
121
+ } catch (err: any) {
122
+ this._triggerCallback('error', err.message, null, this);
123
+ this.state.loading = false;
124
+ }
125
+ });
126
+ };
127
+ return this;
128
+ }
129
+
130
+ /**
131
+ * Load from raw data — array of objects or Record<string, any[]>
132
+ */
133
+ fromData(data: Record<string, any>[] | Record<string, any[]>): this {
134
+ this._pendingSource = async () => {
135
+ this.state.loading = true;
136
+ try {
137
+ const df = new DataFrame(data);
138
+ this._setDataFrame(df, 'inline data');
139
+ } catch (err: any) {
140
+ this._triggerCallback('error', err.message, null, this);
141
+ this.state.loading = false;
142
+ }
143
+ };
144
+ return this;
145
+ }
146
+
147
+ /* ═══════════════════════════════════════════════════
148
+ * TRANSFORM API (returns new DataFrameComponent view)
149
+ * ═══════════════════════════════════════════════════ */
150
+
151
+ /**
152
+ * Apply a transform to the current DataFrame and update the table
153
+ */
154
+ apply(fn: (df: DataFrame) => DataFrame): this {
155
+ if (!this._df) return this;
156
+ const result = fn(this._df);
157
+ this._setDataFrame(result, this.state.sourceName + ' (transformed)');
158
+ this._triggerCallback('transform', result, null, this);
159
+ return this;
160
+ }
161
+
162
+ /**
163
+ * Filter rows
164
+ */
165
+ filter(predicate: (row: Record<string, any>, index: number) => boolean): this {
166
+ return this.apply(df => df.filter(predicate));
167
+ }
168
+
169
+ /**
170
+ * Select columns
171
+ */
172
+ select(...cols: string[]): this {
173
+ return this.apply(df => df.select(...cols));
174
+ }
175
+
176
+ /**
177
+ * Sort by column
178
+ */
179
+ sort(col: string, descending?: boolean): this {
180
+ return this.apply(df => df.sort(col, descending));
181
+ }
182
+
183
+ /**
184
+ * Show first N rows
185
+ */
186
+ head(n: number = 5): this {
187
+ return this.apply(df => df.head(n));
188
+ }
189
+
190
+ /**
191
+ * Show last N rows
192
+ */
193
+ tail(n: number = 5): this {
194
+ return this.apply(df => df.tail(n));
195
+ }
196
+
197
+ /**
198
+ * Add a computed column
199
+ */
200
+ withColumn(name: string, fn: (row: Record<string, any>, index: number) => any): this {
201
+ return this.apply(df => df.withColumn(name, fn));
202
+ }
203
+
204
+ /**
205
+ * Where clause
206
+ */
207
+ where(col: string, op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'contains' | 'startsWith' | 'endsWith', value: any): this {
208
+ return this.apply(df => df.where(col, op, value));
209
+ }
210
+
211
+ /* ═══════════════════════════════════════════════════
212
+ * ACCESSORS
213
+ * ═══════════════════════════════════════════════════ */
214
+
215
+ /** Get the underlying DataFrame */
216
+ get df(): DataFrame | null { return this._df; }
217
+
218
+ /** Get the underlying TabularDriver */
219
+ get driver(): TabularDriver { return this._driver; }
220
+
221
+ /** Get the internal Table component */
222
+ get table(): Table | null { return this._table; }
223
+
224
+ /** Get describe() stats */
225
+ describe(): Record<string, any> | null {
226
+ return this._df?.describe() ?? null;
227
+ }
228
+
229
+ /** Export to CSV string */
230
+ toCSV(delimiter?: string): string {
231
+ return this._df?.toCSV(delimiter) ?? '';
232
+ }
233
+
234
+ /** Export to row objects */
235
+ toRows(): Record<string, any>[] {
236
+ return this._df?.toRows() ?? [];
237
+ }
238
+
239
+ /** Get shape */
240
+ get shape(): [number, number] {
241
+ return this._df?.shape ?? [0, 0];
242
+ }
243
+
244
+ /** Get column names */
245
+ get columns(): string[] {
246
+ return this._df?.columns ?? [];
247
+ }
248
+
249
+ /** Save current DataFrame to IndexedDB */
250
+ async save(key?: string): Promise<string | null> {
251
+ if (!this._df) return null;
252
+ const name = key ?? this._storageKey ?? this._id;
253
+ return this._driver.store(name, this._df);
254
+ }
255
+
256
+ /* ═══════════════════════════════════════════════════
257
+ * TABLE OPTIONS (fluent, pre-render)
258
+ * ═══════════════════════════════════════════════════ */
259
+
260
+ striped(v: boolean): this { this._tableOptions.striped = v; return this; }
261
+ hoverable(v: boolean): this { this._tableOptions.hoverable = v; return this; }
262
+ sortable(v: boolean): this { this._tableOptions.sortable = v; return this; }
263
+ filterable(v: boolean): this { this._tableOptions.filterable = v; return this; }
264
+ paginated(v: boolean): this { this._tableOptions.paginated = v; return this; }
265
+ rowsPerPage(v: number): this { this._tableOptions.rowsPerPage = v; return this; }
266
+
267
+ /* ═══════════════════════════════════════════════════
268
+ * INTERNAL
269
+ * ═══════════════════════════════════════════════════ */
270
+
271
+ private _setDataFrame(df: DataFrame, sourceName: string): void {
272
+ this._df = df;
273
+ this.state.loaded = true;
274
+ this.state.loading = false;
275
+ this.state.sourceName = sourceName;
276
+ this.state.rowCount = df.height;
277
+ this.state.colCount = df.width;
278
+
279
+ // Clean __EMPTY columns from xlsx artifacts
280
+ const cleanCols = df.columns.filter(c => !c.startsWith('__EMPTY'));
281
+ if (cleanCols.length < df.columns.length) {
282
+ this._df = df.select(...cleanCols);
283
+ }
284
+
285
+ this._updateTable();
286
+ this._triggerCallback('load', this._df, null, this);
287
+ }
288
+
289
+ private _updateTable(): void {
290
+ if (!this._table || !this._df) return;
291
+ this._table.columns(this._df.columns).rows(this._df.toRows());
292
+ }
293
+
294
+ update(prop: string, value: any): void { }
295
+
296
+ /* ═══════════════════════════════════════════════════
297
+ * RENDER
298
+ * ═══════════════════════════════════════════════════ */
299
+
300
+ render(targetId?: string | HTMLElement | BaseComponent<any>): this {
301
+ const container = this._setupContainer(targetId);
302
+ const { style, class: className } = this.state;
303
+
304
+ const wrapper = document.createElement('div');
305
+ wrapper.className = 'jux-dataframe';
306
+ wrapper.id = this._id;
307
+ if (className) wrapper.className += ` ${className}`;
308
+ if (style) wrapper.setAttribute('style', style);
309
+
310
+ // Status bar
311
+ const statusBar = document.createElement('div');
312
+ statusBar.className = 'jux-dataframe-status';
313
+ statusBar.id = `${this._id}-status`;
314
+ statusBar.style.cssText = 'font-size:13px;color:#888;margin-bottom:8px;';
315
+ statusBar.textContent = 'No data loaded.';
316
+ wrapper.appendChild(statusBar);
317
+
318
+ container.appendChild(wrapper);
319
+
320
+ // Create internal table
321
+ this._table = new Table(`${this._id}-table`, {
322
+ striped: this._tableOptions.striped,
323
+ hoverable: this._tableOptions.hoverable,
324
+ sortable: this._tableOptions.sortable,
325
+ filterable: this._tableOptions.filterable,
326
+ paginated: this._tableOptions.paginated,
327
+ rowsPerPage: this._tableOptions.rowsPerPage
328
+ });
329
+ this._table.render(wrapper);
330
+
331
+ // Watch state for status updates
332
+ const origUpdate = this.update.bind(this);
333
+ this.update = (prop: string, value: any) => {
334
+ origUpdate(prop, value);
335
+ if (prop === 'loaded' || prop === 'loading' || prop === 'rowCount' || prop === 'colCount' || prop === 'sourceName') {
336
+ const el = document.getElementById(`${this._id}-status`);
337
+ if (el) {
338
+ if (this.state.loading) {
339
+ el.textContent = '⏳ Loading...';
340
+ } else if (this.state.loaded) {
341
+ el.textContent = `✅ ${this.state.sourceName} — ${this.state.rowCount} rows × ${this.state.colCount} cols`;
342
+ } else {
343
+ el.textContent = 'No data loaded.';
344
+ }
345
+ }
346
+ }
347
+ };
348
+
349
+ // Execute pending data source
350
+ if (this._pendingSource) {
351
+ this._pendingSource();
352
+ this._pendingSource = null;
353
+ }
354
+
355
+ this._wireStandardEvents(wrapper);
356
+
357
+ return this;
358
+ }
359
+ }
360
+
361
+ export function dataframe(id: string, options: DataFrameOptions = {}): DataFrameComponent {
362
+ return new DataFrameComponent(id, options);
363
+ }
@@ -39,7 +39,7 @@ export interface TableOptions {
39
39
  }
40
40
  type TableState = {
41
41
  columns: ColumnDef[];
42
- rows: any[][];
42
+ rows: any[];
43
43
  computedColumns: Map<string, ComputedColumnDef>;
44
44
  headers: boolean;
45
45
  striped: boolean;
@@ -71,7 +71,7 @@ export declare class Table extends BaseComponent<TableState> {
71
71
  protected getTriggerEvents(): readonly string[];
72
72
  protected getCallbackEvents(): readonly string[];
73
73
  columns(value: (string | ColumnDef)[]): this;
74
- rows(value: any[][]): this;
74
+ rows(value: any[]): this;
75
75
  /**
76
76
  * Add a computed column that evaluates dynamically at render time
77
77
  *
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["table.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAiBxD,MAAM,MAAM,6BAA6B,GAAG,OAAO,GAAG,UAAU,CAAC;AACjE,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,UAAU,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,WAAW,CAAC;IAExD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,GAAG,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,WAAW,CAAC;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,6BAA6B,CAAC;CACnD;AAED,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,KAAK,GAAG,MAAM,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,6BAA6B,CAAC;CAClD,CAAC;AAOF,qBAAa,KAAM,SAAQ,aAAa,CAAC,UAAU,CAAC;IAClD,OAAO,CAAC,aAAa,CAAiC;gBAE1C,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IAwClD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAWhD,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI;IAO5C,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAwCxB;;;;;;;;OAQG;IACH,cAAc,CACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,GAAG,EAC5C,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,WAAW,EACzE,KAAK,CAAC,EAAE,MAAM,GACb,IAAI;IA8CP;;OAEG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IA0BvC,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI7B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI7B,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI/B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAM7B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAIhC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI/B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMhC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAIhC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAOjC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAoBpC,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAsBtC,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAmB/C,SAAS,IAAI,IAAI;IAiBjB,WAAW,IAAI,IAAI;IAenB,cAAc,IAAI,IAAI;IAKtB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAYnC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAOrC,kBAAkB,IAAI,MAAM,EAAE;IAG9B,eAAe,IAAI,GAAG,EAAE;IASxB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAItC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;IAYlE,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,WAAW;IAqC5F,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,iBAAiB;IAmCzB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,kBAAkB;IAoJ1B,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,aAAa;IAmDrB,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,gBAAgB;IA4ExB,OAAO,CAAC,qBAAqB;IAqC7B,OAAO,CAAC,wBAAwB;IAkBhC,OAAO,CAAC,qBAAqB;IA8B7B,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,iBAAiB;CAiD1B;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAEnE"}
@@ -66,8 +66,7 @@ export interface TableOptions {
66
66
 
67
67
  type TableState = {
68
68
  columns: ColumnDef[];
69
- rows: any[][];
70
- // ✨ NEW: Store computed column definitions
69
+ rows: any[];
71
70
  computedColumns: Map<string, ComputedColumnDef>;
72
71
  headers: boolean;
73
72
  striped: boolean;
@@ -164,7 +163,7 @@ export class Table extends BaseComponent<TableState> {
164
163
  return this;
165
164
  }
166
165
 
167
- rows(value: any[][]): this {
166
+ rows(value: any[]): this {
168
167
  const previousRows = this.state.rows;
169
168
  const hadSelections = this.state.selectedIndexes.size > 0;
170
169
 
@@ -949,7 +948,7 @@ export class Table extends BaseComponent<TableState> {
949
948
  * ═════════════════════════════════════════════════════════════════ */
950
949
 
951
950
  // Data processing
952
- private _getFilteredRows(): any[][] {
951
+ private _getFilteredRows(): any[] {
953
952
  if (!this.state.filterText) return this.state.rows;
954
953
  const searchText = this.state.filterText.toLowerCase();
955
954
  return this.state.rows.filter(row => {
@@ -960,7 +959,7 @@ export class Table extends BaseComponent<TableState> {
960
959
  });
961
960
  }
962
961
 
963
- private _getSortedRows(rows: any[][]): any[][] {
962
+ private _getSortedRows(rows: any[]): any[] {
964
963
  if (!this.state.sortColumn) return rows;
965
964
 
966
965
  // ✨ Check if sorting by computed column
@@ -994,7 +993,7 @@ export class Table extends BaseComponent<TableState> {
994
993
  return sorted;
995
994
  }
996
995
 
997
- private _getPaginatedRows(rows: any[][]): any[][] {
996
+ private _getPaginatedRows(rows: any[]): any[] {
998
997
  if (!this.state.paginated) return rows;
999
998
  const start = (this.state.currentPage - 1) * this.state.rowsPerPage;
1000
999
  const end = start + this.state.rowsPerPage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.163",
3
+ "version": "1.1.165",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "index.js",