@rickcedwhat/playwright-smart-table 6.9.0 → 6.10.1

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 (42) hide show
  1. package/README.md +9 -6
  2. package/dist/engine/rowFinder.js +153 -168
  3. package/dist/engine/tableIteration.js +105 -120
  4. package/dist/engine/tableMapper.js +88 -103
  5. package/dist/minimalConfigContext.d.ts +1 -1
  6. package/dist/minimalConfigContext.js +1 -1
  7. package/dist/packageVersion.d.ts +1 -1
  8. package/dist/packageVersion.js +1 -1
  9. package/dist/presets/glide/columns.js +23 -32
  10. package/dist/presets/glide/headers.js +18 -27
  11. package/dist/presets/glide/index.d.ts +9 -9
  12. package/dist/presets/glide/index.js +24 -33
  13. package/dist/presets/mui.js +197 -124
  14. package/dist/presets/rdg.d.ts +1 -1
  15. package/dist/presets/rdg.js +32 -41
  16. package/dist/smartRow.js +209 -101
  17. package/dist/strategies/columns.js +2 -11
  18. package/dist/strategies/dedupe.js +3 -12
  19. package/dist/strategies/fill.js +20 -29
  20. package/dist/strategies/headers.js +22 -31
  21. package/dist/strategies/index.d.ts +7 -0
  22. package/dist/strategies/index.js +3 -0
  23. package/dist/strategies/loading.js +24 -33
  24. package/dist/strategies/pagination.d.ts +10 -0
  25. package/dist/strategies/pagination.js +49 -30
  26. package/dist/strategies/sorting.js +18 -31
  27. package/dist/strategies/stabilization.js +28 -37
  28. package/dist/strategies/viewport.d.ts +52 -0
  29. package/dist/strategies/viewport.js +123 -0
  30. package/dist/typeContext.d.ts +1 -1
  31. package/dist/typeContext.js +160 -5
  32. package/dist/types.d.ts +153 -5
  33. package/dist/useTable.js +142 -76
  34. package/dist/utils/debugUtils.js +5 -16
  35. package/dist/utils/elementTracker.js +27 -40
  36. package/dist/utils/mutex.js +5 -16
  37. package/dist/utils/navigationBarrier.js +25 -36
  38. package/dist/utils/paginationPath.d.ts +4 -1
  39. package/dist/utils/paginationPath.js +164 -141
  40. package/dist/utils/smartRowArray.js +2 -11
  41. package/dist/utils.js +4 -13
  42. package/package.json +13 -8
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.runForEach = runForEach;
13
4
  exports.runMap = runMap;
@@ -21,134 +12,128 @@ function log(config, msg) {
21
12
  }
22
13
  const SKIP = Symbol('skip');
23
14
  /** Delegates to {@link runMap}; void results are discarded. */
24
- function runForEach(env_1, callback_1) {
25
- return __awaiter(this, arguments, void 0, function* (env, callback, options = {}) {
26
- yield runMap(env, callback, options, 'forEach');
27
- });
15
+ async function runForEach(env, callback, options = {}) {
16
+ await runMap(env, callback, options, 'forEach');
28
17
  }
29
18
  /**
30
19
  * Row iteration for map (and forEach/filter via label).
31
20
  * Concurrency: `parallel` | `synchronized` | `sequential` (see RowIterationOptions).
32
21
  */
33
- function runMap(env_1, callback_1) {
34
- return __awaiter(this, arguments, void 0, function* (env, callback, options = {}, label = 'map') {
35
- var _a, _b, _c, _d, _e;
36
- const map = env.getMap();
37
- const effectiveMaxPages = (_a = options.maxPages) !== null && _a !== void 0 ? _a : env.config.maxPages;
38
- const dedupeStrategy = (_b = options.dedupe) !== null && _b !== void 0 ? _b : env.config.strategies.dedupe;
39
- const dedupeKeys = dedupeStrategy ? new Set() : null;
40
- const defaultMode = label === 'map' ? 'parallel' : 'sequential';
41
- const concurrency = (_d = (_c = options.concurrency) !== null && _c !== void 0 ? _c : env.config.concurrency) !== null && _d !== void 0 ? _d : defaultMode;
42
- const useBarrier = concurrency !== 'sequential';
43
- // Mutex must not pair with the navigation barrier: synchronized mode needs every row
44
- // to enter barrier.sync concurrently; serializing callbacks here deadlocks (first row waits
45
- // for batchSize peers that never reach the barrier).
46
- const useMutex = concurrency === 'sequential';
47
- const useBulk = (_e = options.useBulkPagination) !== null && _e !== void 0 ? _e : false;
48
- const tracker = new elementTracker_1.ElementTracker(label);
49
- log(env.config, `${label}: starting (maxPages=${effectiveMaxPages}, mode=${concurrency}, dedupe=${!!dedupeStrategy})`);
50
- const results = [];
51
- try {
52
- let rowIndex = 0;
53
- let stopped = false;
54
- let stoppedIndex = Infinity;
55
- let pagesScanned = 1;
56
- const stop = (idx) => {
57
- if (!stopped) {
58
- log(env.config, `${label}: stop() called at row ${idx} — halting`);
59
- stopped = true;
60
- stoppedIndex = idx;
61
- }
62
- };
63
- while (!stopped) {
64
- const rowLocators = env.getRowLocators();
65
- const newIndices = yield tracker.getUnseenIndices(rowLocators);
66
- const pageRows = yield rowLocators.all();
67
- const batchSize = newIndices.length;
68
- if (batchSize === 0) {
69
- log(env.config, `${label}: page ${pagesScanned} — no new row(s) found`);
70
- }
71
- else {
72
- log(env.config, `${label}: scanning page ${pagesScanned} — ${batchSize} new row(s)`);
73
- const barrier = useBarrier ? new navigationBarrier_1.NavigationBarrier(batchSize) : undefined;
74
- const actionMutex = useMutex ? new mutex_1.Mutex() : null;
75
- const smartRows = newIndices.map((idx, i) => env.makeSmartRow(pageRows[idx], map, rowIndex + i, pagesScanned - 1, barrier));
76
- const processRow = (row) => __awaiter(this, void 0, void 0, function* () {
77
- try {
78
- if (stopped && row.rowIndex > stoppedIndex) {
22
+ async function runMap(env, callback, options = {}, label = 'map') {
23
+ var _a, _b, _c, _d, _e;
24
+ const map = env.getMap();
25
+ const effectiveMaxPages = (_a = options.maxPages) !== null && _a !== void 0 ? _a : env.config.maxPages;
26
+ const dedupeStrategy = (_b = options.dedupe) !== null && _b !== void 0 ? _b : env.config.strategies.dedupe;
27
+ const dedupeKeys = dedupeStrategy ? new Set() : null;
28
+ const defaultMode = label === 'map' ? 'parallel' : 'sequential';
29
+ const concurrency = (_d = (_c = options.concurrency) !== null && _c !== void 0 ? _c : env.config.concurrency) !== null && _d !== void 0 ? _d : defaultMode;
30
+ const useBarrier = concurrency !== 'sequential';
31
+ // Mutex must not pair with the navigation barrier: synchronized mode needs every row
32
+ // to enter barrier.sync concurrently; serializing callbacks here deadlocks (first row waits
33
+ // for batchSize peers that never reach the barrier).
34
+ const useMutex = concurrency === 'sequential';
35
+ const useBulk = (_e = options.useBulkPagination) !== null && _e !== void 0 ? _e : false;
36
+ const tracker = new elementTracker_1.ElementTracker(label);
37
+ log(env.config, `${label}: starting (maxPages=${effectiveMaxPages}, mode=${concurrency}, dedupe=${!!dedupeStrategy})`);
38
+ const results = [];
39
+ try {
40
+ let rowIndex = 0;
41
+ let stopped = false;
42
+ let stoppedIndex = Infinity;
43
+ let pagesScanned = 1;
44
+ const stop = (idx) => {
45
+ if (!stopped) {
46
+ log(env.config, `${label}: stop() called at row ${idx} — halting`);
47
+ stopped = true;
48
+ stoppedIndex = idx;
49
+ }
50
+ };
51
+ while (!stopped) {
52
+ const rowLocators = env.getRowLocators();
53
+ const newIndices = await tracker.getUnseenIndices(rowLocators);
54
+ const pageRows = await rowLocators.all();
55
+ const batchSize = newIndices.length;
56
+ if (batchSize === 0) {
57
+ log(env.config, `${label}: page ${pagesScanned} — no new row(s) found`);
58
+ }
59
+ else {
60
+ log(env.config, `${label}: scanning page ${pagesScanned} — ${batchSize} new row(s)`);
61
+ const barrier = useBarrier ? new navigationBarrier_1.NavigationBarrier(batchSize) : undefined;
62
+ const actionMutex = useMutex ? new mutex_1.Mutex() : null;
63
+ const smartRows = newIndices.map((idx, i) => env.makeSmartRow(pageRows[idx], map, rowIndex + i, pagesScanned - 1, barrier));
64
+ const processRow = async (row) => {
65
+ try {
66
+ if (stopped && row.rowIndex > stoppedIndex) {
67
+ return SKIP;
68
+ }
69
+ if (dedupeKeys && dedupeStrategy) {
70
+ const key = await dedupeStrategy(row);
71
+ if (dedupeKeys.has(key)) {
72
+ log(env.config, `${label}: dedupe skip key="${key}"`);
79
73
  return SKIP;
80
74
  }
81
- if (dedupeKeys && dedupeStrategy) {
82
- const key = yield dedupeStrategy(row);
83
- if (dedupeKeys.has(key)) {
84
- log(env.config, `${label}: dedupe skip key="${key}"`);
85
- return SKIP;
86
- }
87
- dedupeKeys.add(key);
88
- }
89
- // Execute callback (optionally serialized via mutex)
90
- const runCallback = () => __awaiter(this, void 0, void 0, function* () {
91
- if (stopped && row.rowIndex > stoppedIndex)
92
- return SKIP;
93
- log(env.config, `${label}: processing row ${row.rowIndex}`);
94
- return yield callback({ row, rowIndex: row.rowIndex, stop: () => stop(row.rowIndex) });
95
- });
96
- if (actionMutex) {
97
- return yield actionMutex.run(runCallback);
98
- }
99
- else {
100
- return yield runCallback();
101
- }
75
+ dedupeKeys.add(key);
102
76
  }
103
- finally {
104
- // Ensure the barrier is notified once per row, even on error or skip.
105
- barrier === null || barrier === void 0 ? void 0 : barrier.markFinished();
77
+ // Execute callback (optionally serialized via mutex)
78
+ const runCallback = async () => {
79
+ if (stopped && row.rowIndex > stoppedIndex)
80
+ return SKIP;
81
+ log(env.config, `${label}: processing row ${row.rowIndex}`);
82
+ return await callback({ row, rowIndex: row.rowIndex, stop: () => stop(row.rowIndex) });
83
+ };
84
+ if (actionMutex) {
85
+ return await actionMutex.run(runCallback);
106
86
  }
107
- });
108
- const pageResults = [];
109
- if (concurrency === 'sequential') {
110
- for (const row of smartRows) {
111
- pageResults.push(yield processRow(row));
87
+ else {
88
+ return await runCallback();
112
89
  }
113
90
  }
114
- else {
115
- const results = yield Promise.all(smartRows.map(processRow));
116
- pageResults.push(...results);
91
+ finally {
92
+ // Ensure the barrier is notified once per row, even on error or skip.
93
+ barrier === null || barrier === void 0 ? void 0 : barrier.markFinished();
117
94
  }
118
- for (let i = 0; i < pageResults.length; i++) {
119
- if (smartRows[i].rowIndex > stoppedIndex)
120
- break;
121
- const r = pageResults[i];
122
- if (r !== SKIP)
123
- results.push(r);
95
+ };
96
+ const pageResults = [];
97
+ if (concurrency === 'sequential') {
98
+ for (const row of smartRows) {
99
+ pageResults.push(await processRow(row));
124
100
  }
125
- rowIndex += batchSize;
126
101
  }
127
- if (stopped || pagesScanned >= effectiveMaxPages)
128
- break;
129
- log(env.config, `${label}: advancing to next page (${pagesScanned} → ${pagesScanned + 1})`);
130
- if (!(yield env.advancePage(useBulk))) {
131
- log(env.config, `${label}: no more pages — done`);
132
- break;
102
+ else {
103
+ const results = await Promise.all(smartRows.map(processRow));
104
+ pageResults.push(...results);
133
105
  }
134
- pagesScanned++;
106
+ for (let i = 0; i < pageResults.length; i++) {
107
+ if (smartRows[i].rowIndex > stoppedIndex)
108
+ break;
109
+ const r = pageResults[i];
110
+ if (r !== SKIP)
111
+ results.push(r);
112
+ }
113
+ rowIndex += batchSize;
135
114
  }
136
- log(env.config, `${label}: complete — ${results.length} result(s) across ${pagesScanned} page(s)`);
137
- }
138
- finally {
139
- yield tracker.cleanup(env.getPage());
115
+ if (stopped || pagesScanned >= effectiveMaxPages)
116
+ break;
117
+ log(env.config, `${label}: advancing to next page (${pagesScanned} → ${pagesScanned + 1})`);
118
+ if (!await env.advancePage(useBulk)) {
119
+ log(env.config, `${label}: no more pages — done`);
120
+ break;
121
+ }
122
+ pagesScanned++;
140
123
  }
141
- return results;
142
- });
124
+ log(env.config, `${label}: complete — ${results.length} result(s) across ${pagesScanned} page(s)`);
125
+ }
126
+ finally {
127
+ await tracker.cleanup(env.getPage());
128
+ }
129
+ return results;
143
130
  }
144
131
  /** Filter via map; returns matched rows as {@link SmartRowArray}. */
145
- function runFilter(env_1, predicate_1) {
146
- return __awaiter(this, arguments, void 0, function* (env, predicate, options = {}) {
147
- const mapCallback = (ctx) => __awaiter(this, void 0, void 0, function* () {
148
- const matched = yield predicate(ctx);
149
- return matched ? ctx.row : SKIP;
150
- });
151
- const results = yield runMap(env, mapCallback, options, 'filter');
152
- return env.createSmartRowArray(results);
153
- });
132
+ async function runFilter(env, predicate, options = {}) {
133
+ const mapCallback = async (ctx) => {
134
+ const matched = await predicate(ctx);
135
+ return matched ? ctx.row : SKIP;
136
+ };
137
+ const results = await runMap(env, mapCallback, options, 'filter');
138
+ return env.createSmartRowArray(results);
154
139
  }
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.TableMapper = void 0;
13
4
  const headers_1 = require("../strategies/headers");
@@ -22,69 +13,65 @@ class TableMapper {
22
13
  log(msg) {
23
14
  (0, debugUtils_1.logDebug)(this.config, 'verbose', msg);
24
15
  }
25
- getMap(timeout) {
26
- return __awaiter(this, void 0, void 0, function* () {
27
- var _a;
28
- if (this._headerMap)
29
- return this._headerMap;
30
- this.log('Mapping headers...');
31
- const headerTimeout = timeout !== null && timeout !== void 0 ? timeout : 3000;
32
- const startTime = Date.now();
33
- if (this.config.autoScroll) {
34
- try {
35
- yield this.rootLocator.scrollIntoViewIfNeeded({ timeout: 1000 });
36
- }
37
- catch (e) { }
16
+ async getMap(timeout) {
17
+ var _a;
18
+ if (this._headerMap)
19
+ return this._headerMap;
20
+ this.log('Mapping headers...');
21
+ const headerTimeout = timeout !== null && timeout !== void 0 ? timeout : 3000;
22
+ const startTime = Date.now();
23
+ if (this.config.autoScroll) {
24
+ try {
25
+ await this.rootLocator.scrollIntoViewIfNeeded({ timeout: 1000 });
38
26
  }
39
- const headerLoc = this.resolve(this.config.headerSelector, this.rootLocator);
40
- const strategy = this.config.strategies.header || headers_1.HeaderStrategies.visible;
41
- const context = {
42
- root: this.rootLocator,
43
- config: this.config,
44
- page: this.rootLocator.page(),
45
- resolve: this.resolve
46
- };
47
- let lastError = null;
48
- while (Date.now() - startTime < headerTimeout) {
49
- // 1. Wait for visibility
50
- try {
51
- yield headerLoc.first().waitFor({ state: 'visible', timeout: 200 });
52
- }
53
- catch (e) {
54
- // Continue to check existing/loading state even if not strictly "visible" yet
55
- }
56
- // 2. Check Smart Loading State
57
- if ((_a = this.config.strategies.loading) === null || _a === void 0 ? void 0 : _a.isHeaderLoading) {
58
- const isStable = !(yield this.config.strategies.loading.isHeaderLoading(context));
59
- if (!isStable) {
60
- this.log('Headers are loading/unstable... waiting');
61
- yield new Promise(r => setTimeout(r, 100));
62
- continue;
63
- }
64
- }
65
- // 3. Attempt Scan
66
- try {
67
- const rawHeaders = yield strategy(context);
68
- const entries = yield this.processHeaders(rawHeaders);
69
- // Success
70
- this._headerMap = new Map(entries);
71
- this.log(`Mapped ${entries.length} columns: ${JSON.stringify(entries.map(e => e[0]))}`);
72
- return this._headerMap;
73
- }
74
- catch (e) {
75
- lastError = e;
76
- this.log(`Header mapping failed. Attempt ${Math.floor((Date.now() - startTime) / 100)}: ${e.message}`);
77
- yield new Promise(r => setTimeout(r, 100));
27
+ catch (e) { }
28
+ }
29
+ const headerLoc = this.resolve(this.config.headerSelector, this.rootLocator);
30
+ const strategy = this.config.strategies.header || headers_1.HeaderStrategies.visible;
31
+ const context = {
32
+ root: this.rootLocator,
33
+ config: this.config,
34
+ page: this.rootLocator.page(),
35
+ resolve: this.resolve
36
+ };
37
+ let lastError = null;
38
+ while (Date.now() - startTime < headerTimeout) {
39
+ // 1. Wait for visibility
40
+ try {
41
+ await headerLoc.first().waitFor({ state: 'visible', timeout: 200 });
42
+ }
43
+ catch (e) {
44
+ // Continue to check existing/loading state even if not strictly "visible" yet
45
+ }
46
+ // 2. Check Smart Loading State
47
+ if ((_a = this.config.strategies.loading) === null || _a === void 0 ? void 0 : _a.isHeaderLoading) {
48
+ const isStable = !(await this.config.strategies.loading.isHeaderLoading(context));
49
+ if (!isStable) {
50
+ this.log('Headers are loading/unstable... waiting');
51
+ await new Promise(r => setTimeout(r, 100));
52
+ continue;
78
53
  }
79
54
  }
80
- throw lastError || new Error(`Timed out waiting for headers after ${headerTimeout}ms`);
81
- });
55
+ // 3. Attempt Scan
56
+ try {
57
+ const rawHeaders = await strategy(context);
58
+ const entries = await this.processHeaders(rawHeaders);
59
+ // Success
60
+ this._headerMap = new Map(entries);
61
+ this.log(`Mapped ${entries.length} columns: ${JSON.stringify(entries.map(e => e[0]))}`);
62
+ return this._headerMap;
63
+ }
64
+ catch (e) {
65
+ lastError = e;
66
+ this.log(`Header mapping failed. Attempt ${Math.floor((Date.now() - startTime) / 100)}: ${e.message}`);
67
+ await new Promise(r => setTimeout(r, 100));
68
+ }
69
+ }
70
+ throw lastError || new Error(`Timed out waiting for headers after ${headerTimeout}ms`);
82
71
  }
83
- remapHeaders() {
84
- return __awaiter(this, void 0, void 0, function* () {
85
- this._headerMap = null;
86
- yield this.getMap();
87
- });
72
+ async remapHeaders() {
73
+ this._headerMap = null;
74
+ await this.getMap();
88
75
  }
89
76
  getMapSync() {
90
77
  return this._headerMap;
@@ -95,43 +82,41 @@ class TableMapper {
95
82
  clear() {
96
83
  this._headerMap = null;
97
84
  }
98
- processHeaders(rawHeaders) {
99
- return __awaiter(this, void 0, void 0, function* () {
100
- const seenHeaders = new Set();
101
- const entries = [];
102
- for (let i = 0; i < rawHeaders.length; i++) {
103
- let text = rawHeaders[i].trim() || `__col_${i}`;
104
- if (this.config.headerTransformer) {
105
- text = yield this.config.headerTransformer({
106
- text,
107
- index: i,
108
- locator: this.resolve(this.config.headerSelector, this.rootLocator).nth(i),
109
- seenHeaders
110
- });
111
- }
112
- this.log(`Header mapping index ${i}: "${text}"`);
113
- entries.push([text, i]);
114
- seenHeaders.add(text);
115
- }
116
- // Validation: Check for empty table
117
- if (entries.length === 0) {
118
- throw new Error(`Initialization Error: No columns found using selector "${this.config.headerSelector}". Check your selector or ensure the table is visible.`);
119
- }
120
- // Validation: Check for duplicates
121
- const seen = new Set();
122
- const duplicates = new Set();
123
- for (const [name] of entries) {
124
- if (seen.has(name)) {
125
- duplicates.add(name);
126
- }
127
- seen.add(name);
85
+ async processHeaders(rawHeaders) {
86
+ const seenHeaders = new Set();
87
+ const entries = [];
88
+ for (let i = 0; i < rawHeaders.length; i++) {
89
+ let text = rawHeaders[i].trim() || `__col_${i}`;
90
+ if (this.config.headerTransformer) {
91
+ text = await this.config.headerTransformer({
92
+ text,
93
+ index: i,
94
+ locator: this.resolve(this.config.headerSelector, this.rootLocator).nth(i),
95
+ seenHeaders
96
+ });
128
97
  }
129
- if (duplicates.size > 0) {
130
- const dupList = Array.from(duplicates).map(d => `"${d}"`).join(', ');
131
- throw new Error(`Initialization Error: Duplicate column names found: ${dupList}. Use 'headerTransformer' to rename duplicate columns.`);
98
+ this.log(`Header mapping index ${i}: "${text}"`);
99
+ entries.push([text, i]);
100
+ seenHeaders.add(text);
101
+ }
102
+ // Validation: Check for empty table
103
+ if (entries.length === 0) {
104
+ throw new Error(`Initialization Error: No columns found using selector "${this.config.headerSelector}". Check your selector or ensure the table is visible.`);
105
+ }
106
+ // Validation: Check for duplicates
107
+ const seen = new Set();
108
+ const duplicates = new Set();
109
+ for (const [name] of entries) {
110
+ if (seen.has(name)) {
111
+ duplicates.add(name);
132
112
  }
133
- return entries;
134
- });
113
+ seen.add(name);
114
+ }
115
+ if (duplicates.size > 0) {
116
+ const dupList = Array.from(duplicates).map(d => `"${d}"`).join(', ');
117
+ throw new Error(`Initialization Error: Duplicate column names found: ${dupList}. Use 'headerTransformer' to rename duplicate columns.`);
118
+ }
119
+ return entries;
135
120
  }
136
121
  }
137
122
  exports.TableMapper = TableMapper;
@@ -3,4 +3,4 @@
3
3
  * This file is generated by scripts/embed-config-types.mjs
4
4
  * It contains minimal type definitions for config generation prompts.
5
5
  */
6
- export declare const MINIMAL_CONFIG_CONTEXT = "\n/**\n * Flexible selector type - can be a CSS string or function returning a Locator.\n * @example\n * // String selector\n * rowSelector: 'tbody tr'\n * \n * // Function selector\n * rowSelector: (root) => root.locator('[role=\"row\"]')\n */\nexport type Selector = string | ((root: Locator | Page) => Locator);\n\n/**\n * Debug configuration for development and troubleshooting\n */\nexport type DebugConfig = {\n slow?: number | {\n pagination?: number;\n getCell?: number;\n findRow?: number;\n default?: number;\n };\n logLevel?: 'verbose' | 'info' | 'error' | 'none';\n};\n\n/**\n * Configuration options for useTable - focus on selectors and basic setup\n */\nexport interface TableConfig<T = any> {\n /** CSS selector or function for table headers */\n headerSelector?: string | ((root: Locator) => Locator);\n \n /** CSS selector or function for table rows */\n rowSelector?: string | ((root: Locator) => Locator);\n \n /** CSS selector or function for cells within a row */\n cellSelector?: string | ((row: Locator) => Locator);\n \n /** Transform header text (e.g., normalize, deduplicate) */\n headerTransformer?: (args: { \n text: string; \n index: number; \n locator: Locator;\n seenHeaders: Set<string>;\n }) => string | Promise<string>;\n \n /** Automatically scroll to table on init (default: true) */\n autoScroll?: boolean;\n \n /** Debug options for development and troubleshooting */\n debug?: DebugConfig;\n \n /** Advanced: Custom strategies for pagination, sorting, navigation, etc. */\n strategies?: TableStrategies;\n}\n\n/**\n * Example usage:\n */\n// const table = useTable(page.locator('table'), {\n// headerSelector: 'thead th',\n// rowSelector: 'tbody tr',\n// cellSelector: 'td',\n// headerTransformer: ({ text }) => text.trim()\n// });\n\n";
6
+ export declare const MINIMAL_CONFIG_CONTEXT = "\n/**\n * Flexible selector type - can be a CSS string or function returning a Locator.\n * @example\n * // String selector\n * rowSelector: 'tbody tr'\n * \n * // Function selector\n * headerSelector: (root) => root.locator('[role=\"columnheader\"]')\n */\nexport type Selector = string | ((root: Locator | Page) => Locator);\n\n/**\n * Debug configuration for development and troubleshooting\n */\nexport type DebugConfig = {\n slow?: number | {\n pagination?: number;\n getCell?: number;\n findRow?: number;\n default?: number;\n };\n logLevel?: 'verbose' | 'info' | 'error' | 'none';\n};\n\n/**\n * Configuration options for useTable - focus on selectors and basic setup\n */\nexport interface TableConfig<T = any> {\n /** CSS selector or function for table headers */\n headerSelector?: string | ((root: Locator) => Locator);\n \n /** CSS selector or function for table rows */\n rowSelector?: string | ((root: Locator) => Locator);\n \n /** CSS selector or function for cells within a row */\n cellSelector?: string | ((row: Locator) => Locator);\n \n /** Transform header text (e.g., normalize, deduplicate) */\n headerTransformer?: (args: { \n text: string; \n index: number; \n locator: Locator;\n seenHeaders: Set<string>;\n }) => string | Promise<string>;\n \n /** Automatically scroll to table on init (default: true) */\n autoScroll?: boolean;\n \n /** Debug options for development and troubleshooting */\n debug?: DebugConfig;\n \n /** Advanced: Custom strategies for pagination, sorting, navigation, etc. */\n strategies?: TableStrategies;\n}\n\n/**\n * Example usage:\n */\n// const table = useTable(page.locator('table'), {\n// headerSelector: 'thead th',\n// rowSelector: 'tbody tr',\n// cellSelector: 'td',\n// headerTransformer: ({ text }) => text.trim()\n// });\n\n";
@@ -14,7 +14,7 @@ exports.MINIMAL_CONFIG_CONTEXT = `
14
14
  * rowSelector: 'tbody tr'
15
15
  *
16
16
  * // Function selector
17
- * rowSelector: (root) => root.locator('[role="row"]')
17
+ * headerSelector: (root) => root.locator('[role="columnheader"]')
18
18
  */
19
19
  export type Selector = string | ((root: Locator | Page) => Locator);
20
20
 
@@ -3,4 +3,4 @@
3
3
  * Generated by scripts/embed-version.mjs from package.json
4
4
  */
5
5
  /** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
6
- export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.9.0";
6
+ export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.10.1";
@@ -6,4 +6,4 @@ exports.PLAYWRIGHT_SMART_TABLE_VERSION = void 0;
6
6
  * Generated by scripts/embed-version.mjs from package.json
7
7
  */
8
8
  /** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
9
- exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.9.0";
9
+ exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.10.1";
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.glideSnapFirstColumnIntoView = exports.glideSeekColumnIndex = exports.glideGoRight = exports.glideGoLeft = exports.glideGoDown = exports.glideGoUp = void 0;
13
4
  /**
@@ -15,48 +6,48 @@ exports.glideSnapFirstColumnIntoView = exports.glideSeekColumnIndex = exports.gl
15
6
  * These define HOW to move, not WHEN to move.
16
7
  * The orchestration logic lives in _navigateToCell.
17
8
  */
18
- const glideGoUp = (context) => __awaiter(void 0, void 0, void 0, function* () {
19
- yield context.page.keyboard.press('ArrowUp');
20
- });
9
+ const glideGoUp = async (context) => {
10
+ await context.page.keyboard.press('ArrowUp');
11
+ };
21
12
  exports.glideGoUp = glideGoUp;
22
- const glideGoDown = (context) => __awaiter(void 0, void 0, void 0, function* () {
23
- yield context.page.keyboard.press('ArrowDown');
24
- });
13
+ const glideGoDown = async (context) => {
14
+ await context.page.keyboard.press('ArrowDown');
15
+ };
25
16
  exports.glideGoDown = glideGoDown;
26
17
  // Horizontal: use page `.dvn-scroller` (canvas root is not its ancestor). Virtualized rows expose
27
18
  // a small window of `td[aria-colindex]` that shifts with scrollLeft.
28
- const nudgePageScroller = (page, delta) => __awaiter(void 0, void 0, void 0, function* () {
19
+ const nudgePageScroller = async (page, delta) => {
29
20
  const scroller = page.locator('.dvn-scroller').first();
30
- yield scroller.evaluate((el, d) => {
21
+ await scroller.evaluate((el, d) => {
31
22
  el.scrollLeft += d;
32
23
  }, delta);
33
- });
34
- const glideGoLeft = (context) => __awaiter(void 0, void 0, void 0, function* () {
35
- yield nudgePageScroller(context.page, -400);
36
- });
24
+ };
25
+ const glideGoLeft = async (context) => {
26
+ await nudgePageScroller(context.page, -400);
27
+ };
37
28
  exports.glideGoLeft = glideGoLeft;
38
- const glideGoRight = (context) => __awaiter(void 0, void 0, void 0, function* () {
39
- yield nudgePageScroller(context.page, 400);
40
- });
29
+ const glideGoRight = async (context) => {
30
+ await nudgePageScroller(context.page, 400);
31
+ };
41
32
  exports.glideGoRight = glideGoRight;
42
33
  /** Coarse `scrollLeft` toward `columnIndex`; `goLeft`/`goRight` correct the remainder. */
43
- const glideSeekColumnIndex = (context, columnIndex) => __awaiter(void 0, void 0, void 0, function* () {
34
+ const glideSeekColumnIndex = async (context, columnIndex) => {
44
35
  const { page } = context;
45
36
  const scroller = page.locator('.dvn-scroller').first();
46
- yield scroller.evaluate((el, colIdx) => {
37
+ await scroller.evaluate((el, colIdx) => {
47
38
  const max = Math.max(0, el.scrollWidth - el.clientWidth);
48
39
  const ratio = Math.min(1, Math.max(0, (colIdx + 0.5) / 64));
49
40
  el.scrollLeft = Math.floor(ratio * max);
50
41
  }, columnIndex);
51
- yield page.waitForTimeout(100);
52
- });
42
+ await page.waitForTimeout(100);
43
+ };
53
44
  exports.glideSeekColumnIndex = glideSeekColumnIndex;
54
45
  /** `scrollLeft = 0` so low `aria-colindex` cells exist again (see smartRow for optional `Home`). */
55
- const glideSnapFirstColumnIntoView = (context) => __awaiter(void 0, void 0, void 0, function* () {
46
+ const glideSnapFirstColumnIntoView = async (context) => {
56
47
  const { page } = context;
57
- yield page.locator('.dvn-scroller').first().evaluate((el) => {
48
+ await page.locator('.dvn-scroller').first().evaluate((el) => {
58
49
  el.scrollLeft = 0;
59
50
  });
60
- yield page.waitForTimeout(150);
61
- });
51
+ await page.waitForTimeout(150);
52
+ };
62
53
  exports.glideSnapFirstColumnIntoView = glideSnapFirstColumnIntoView;