@rickcedwhat/playwright-smart-table 6.7.4 → 6.7.5

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 (38) hide show
  1. package/dist/engine/rowFinder.d.ts +1 -1
  2. package/dist/engine/rowFinder.js +5 -4
  3. package/dist/engine/tableIteration.d.ts +25 -0
  4. package/dist/engine/tableIteration.js +210 -0
  5. package/dist/plugins/glide/columns.d.ts +11 -0
  6. package/dist/plugins/glide/columns.js +51 -0
  7. package/dist/plugins/glide/headers.d.ts +9 -0
  8. package/dist/plugins/glide/headers.js +65 -0
  9. package/dist/plugins/glide/index.d.ts +31 -0
  10. package/dist/plugins/glide/index.js +104 -0
  11. package/dist/plugins/glide.d.ts +31 -0
  12. package/dist/plugins/glide.js +104 -0
  13. package/dist/plugins/index.d.ts +16 -0
  14. package/dist/plugins/index.js +16 -0
  15. package/dist/plugins/mui/index.d.ts +8 -0
  16. package/dist/plugins/mui/index.js +25 -0
  17. package/dist/plugins/mui.d.ts +8 -0
  18. package/dist/plugins/mui.js +25 -0
  19. package/dist/plugins/rdg/index.d.ts +17 -0
  20. package/dist/plugins/rdg/index.js +124 -0
  21. package/dist/plugins/rdg.d.ts +17 -0
  22. package/dist/plugins/rdg.js +124 -0
  23. package/dist/plugins.d.ts +12 -40
  24. package/dist/plugins.js +9 -6
  25. package/dist/smartRow.js +22 -7
  26. package/dist/strategies/glide.d.ts +6 -20
  27. package/dist/strategies/glide.js +22 -12
  28. package/dist/strategies/mui.d.ts +8 -0
  29. package/dist/strategies/mui.js +25 -0
  30. package/dist/strategies/rdg.d.ts +5 -22
  31. package/dist/strategies/rdg.js +23 -10
  32. package/dist/typeContext.d.ts +1 -1
  33. package/dist/typeContext.js +12 -11
  34. package/dist/types.d.ts +12 -18
  35. package/dist/useTable.js +46 -183
  36. package/dist/utils/sentinel.d.ts +5 -0
  37. package/dist/utils/sentinel.js +8 -0
  38. package/package.json +1 -1
package/dist/useTable.js CHANGED
@@ -32,6 +32,7 @@ const smartRow_1 = require("./smartRow");
32
32
  const filterEngine_1 = require("./filterEngine");
33
33
  const tableMapper_1 = require("./engine/tableMapper");
34
34
  const rowFinder_1 = require("./engine/rowFinder");
35
+ const tableIteration_1 = require("./engine/tableIteration");
35
36
  const debugUtils_1 = require("./utils/debugUtils");
36
37
  const smartRowArray_1 = require("./utils/smartRowArray");
37
38
  const elementTracker_1 = require("./utils/elementTracker");
@@ -95,6 +96,8 @@ const useTable = (rootLocator, configOptions = {}) => {
95
96
  };
96
97
  const tableState = { currentPageIndex: 0 };
97
98
  const rowFinder = new rowFinder_1.RowFinder(rootLocator, config, resolve, filterEngine, tableMapper, _makeSmart, tableState);
99
+ /** Builds a full TableContext/StrategyContext with getHeaderCell, getHeaders, scrollToColumn. Set after result is created. */
100
+ let createStrategyContext = () => ({ root: rootLocator, config, page: rootLocator.page(), resolve });
98
101
  const _getCleanHtml = (loc) => __awaiter(void 0, void 0, void 0, function* () {
99
102
  return loc.evaluate((el) => {
100
103
  const clone = el.cloneNode(true);
@@ -128,7 +131,7 @@ const useTable = (rootLocator, configOptions = {}) => {
128
131
  });
129
132
  // Default: goNext (one page). Pass useBulk true to prefer goNextBulk. "How far" uses numeric return when strategy provides it.
130
133
  const _advancePage = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (useBulk = false) {
131
- const context = { root: rootLocator, config, page: rootLocator.page(), resolve, getHeaderCell: result.getHeaderCell, getHeaders: result.getHeaders, scrollToColumn: result.scrollToColumn };
134
+ const context = createStrategyContext();
132
135
  const pagination = config.strategies.pagination;
133
136
  let rawResult;
134
137
  if (useBulk && (pagination === null || pagination === void 0 ? void 0 : pagination.goNextBulk)) {
@@ -183,11 +186,10 @@ const useTable = (rootLocator, configOptions = {}) => {
183
186
  reset: () => __awaiter(void 0, void 0, void 0, function* () {
184
187
  var _a;
185
188
  log("Resetting table...");
186
- const context = { root: rootLocator, config, page: rootLocator.page(), resolve, getHeaderCell: result.getHeaderCell };
187
- yield config.onReset(context);
189
+ yield config.onReset(createStrategyContext());
188
190
  if ((_a = config.strategies.pagination) === null || _a === void 0 ? void 0 : _a.goToFirst) {
189
191
  log("Auto-navigating to first page...");
190
- yield config.strategies.pagination.goToFirst(context);
192
+ yield config.strategies.pagination.goToFirst(createStrategyContext());
191
193
  }
192
194
  else if (hasPaginationInConfig) {
193
195
  log("No goToFirst strategy configured. Table may not be on page 1.");
@@ -220,11 +222,10 @@ const useTable = (rootLocator, configOptions = {}) => {
220
222
  return _makeSmart(rowLocator, map, index);
221
223
  },
222
224
  findRow: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
223
- // @ts-ignore
224
225
  return rowFinder.findRow(filters, options);
225
226
  }),
226
227
  findRows: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
227
- return rowFinder.findRows(filters, options);
228
+ return rowFinder.findRows(filters !== null && filters !== void 0 ? filters : {}, options);
228
229
  }),
229
230
  isInitialized: () => {
230
231
  return tableMapper.isInitialized();
@@ -236,7 +237,7 @@ const useTable = (rootLocator, configOptions = {}) => {
236
237
  if (!config.strategies.sorting)
237
238
  throw new Error('No sorting strategy has been configured.');
238
239
  log(`Applying sort for column "${columnName}" (${direction})`);
239
- const context = { root: rootLocator, config, page: rootLocator.page(), resolve, getHeaderCell: result.getHeaderCell };
240
+ const context = Object.assign(Object.assign({}, createStrategyContext()), { getHeaderCell: result.getHeaderCell });
240
241
  const maxRetries = 3;
241
242
  for (let i = 0; i < maxRetries; i++) {
242
243
  const currentState = yield config.strategies.sorting.getSortState({ columnName, context });
@@ -264,7 +265,7 @@ const useTable = (rootLocator, configOptions = {}) => {
264
265
  yield _autoInit();
265
266
  if (!config.strategies.sorting)
266
267
  throw new Error('No sorting strategy has been configured.');
267
- const context = { root: rootLocator, config, page: rootLocator.page(), resolve, getHeaderCell: result.getHeaderCell };
268
+ const context = Object.assign(Object.assign({}, createStrategyContext()), { getHeaderCell: result.getHeaderCell });
268
269
  return config.strategies.sorting.getSortState({ columnName, context });
269
270
  })
270
271
  },
@@ -299,189 +300,42 @@ const useTable = (rootLocator, configOptions = {}) => {
299
300
  }
300
301
  });
301
302
  },
302
- // ─── Private row-iteration engine ────────────────────────────────────────
303
+ // ─── Row iteration (delegated to engine/tableIteration) ──────────────────
303
304
  forEach: (callback_1, ...args_1) => __awaiter(void 0, [callback_1, ...args_1], void 0, function* (callback, options = {}) {
304
- var _a, _b, _c, _d;
305
305
  yield _autoInit();
306
- const map = tableMapper.getMapSync();
307
- const effectiveMaxPages = (_a = options.maxPages) !== null && _a !== void 0 ? _a : config.maxPages;
308
- const dedupeStrategy = (_b = options.dedupe) !== null && _b !== void 0 ? _b : config.strategies.dedupe;
309
- const dedupeKeys = dedupeStrategy ? new Set() : null;
310
- const parallel = (_c = options.parallel) !== null && _c !== void 0 ? _c : false;
311
- const useBulk = (_d = options.useBulkPagination) !== null && _d !== void 0 ? _d : false;
312
- const tracker = new elementTracker_1.ElementTracker('forEach');
313
- try {
314
- let rowIndex = 0;
315
- let stopped = false;
316
- let pagesScanned = 1;
317
- const stop = () => { stopped = true; };
318
- while (!stopped) {
319
- const rowLocators = resolve(config.rowSelector, rootLocator);
320
- const newIndices = yield tracker.getUnseenIndices(rowLocators);
321
- const pageRows = yield rowLocators.all();
322
- const smartRows = newIndices.map((idx, i) => _makeSmart(pageRows[idx], map, rowIndex + i));
323
- if (parallel) {
324
- yield Promise.all(smartRows.map((row) => __awaiter(void 0, void 0, void 0, function* () {
325
- if (stopped)
326
- return;
327
- if (dedupeKeys) {
328
- const key = yield dedupeStrategy(row);
329
- if (dedupeKeys.has(key))
330
- return;
331
- dedupeKeys.add(key);
332
- }
333
- yield callback({ row, rowIndex: row.rowIndex, stop });
334
- })));
335
- }
336
- else {
337
- for (const row of smartRows) {
338
- if (stopped)
339
- break;
340
- if (dedupeKeys) {
341
- const key = yield dedupeStrategy(row);
342
- if (dedupeKeys.has(key))
343
- continue;
344
- dedupeKeys.add(key);
345
- }
346
- yield callback({ row, rowIndex: row.rowIndex, stop });
347
- }
348
- }
349
- rowIndex += smartRows.length;
350
- if (stopped || pagesScanned >= effectiveMaxPages)
351
- break;
352
- if (!(yield _advancePage(useBulk)))
353
- break;
354
- pagesScanned++;
355
- }
356
- }
357
- finally {
358
- yield tracker.cleanup(rootLocator.page());
359
- }
306
+ yield (0, tableIteration_1.runForEach)({
307
+ getRowLocators: () => resolve(config.rowSelector, rootLocator),
308
+ getMap: () => tableMapper.getMapSync(),
309
+ advancePage: _advancePage,
310
+ makeSmartRow: (loc, map, idx, pageIdx) => _makeSmart(loc, map, idx, pageIdx),
311
+ createSmartRowArray: smartRowArray_1.createSmartRowArray,
312
+ config,
313
+ getPage: () => rootLocator.page(),
314
+ }, callback, options);
360
315
  }),
361
316
  map: (callback_1, ...args_1) => __awaiter(void 0, [callback_1, ...args_1], void 0, function* (callback, options = {}) {
362
- var _a, _b, _c, _d;
363
317
  yield _autoInit();
364
- const map = tableMapper.getMapSync();
365
- const effectiveMaxPages = (_a = options.maxPages) !== null && _a !== void 0 ? _a : config.maxPages;
366
- const dedupeStrategy = (_b = options.dedupe) !== null && _b !== void 0 ? _b : config.strategies.dedupe;
367
- const dedupeKeys = dedupeStrategy ? new Set() : null;
368
- const parallel = (_c = options.parallel) !== null && _c !== void 0 ? _c : true;
369
- const useBulk = (_d = options.useBulkPagination) !== null && _d !== void 0 ? _d : false;
370
- const tracker = new elementTracker_1.ElementTracker('map');
371
- const results = [];
372
- try {
373
- let rowIndex = 0;
374
- let stopped = false;
375
- let pagesScanned = 1;
376
- const stop = () => { stopped = true; };
377
- while (!stopped) {
378
- const rowLocators = resolve(config.rowSelector, rootLocator);
379
- const newIndices = yield tracker.getUnseenIndices(rowLocators);
380
- const pageRows = yield rowLocators.all();
381
- const smartRows = newIndices.map((idx, i) => _makeSmart(pageRows[idx], map, rowIndex + i));
382
- if (parallel) {
383
- const SKIP = Symbol('skip');
384
- const pageResults = yield Promise.all(smartRows.map((row) => __awaiter(void 0, void 0, void 0, function* () {
385
- if (dedupeKeys) {
386
- const key = yield dedupeStrategy(row);
387
- if (dedupeKeys.has(key))
388
- return SKIP;
389
- dedupeKeys.add(key);
390
- }
391
- return callback({ row, rowIndex: row.rowIndex, stop });
392
- })));
393
- for (const r of pageResults) {
394
- if (r !== SKIP)
395
- results.push(r);
396
- }
397
- }
398
- else {
399
- for (const row of smartRows) {
400
- if (stopped)
401
- break;
402
- if (dedupeKeys) {
403
- const key = yield dedupeStrategy(row);
404
- if (dedupeKeys.has(key))
405
- continue;
406
- dedupeKeys.add(key);
407
- }
408
- results.push(yield callback({ row, rowIndex: row.rowIndex, stop }));
409
- }
410
- }
411
- rowIndex += smartRows.length;
412
- if (stopped || pagesScanned >= effectiveMaxPages)
413
- break;
414
- if (!(yield _advancePage(useBulk)))
415
- break;
416
- pagesScanned++;
417
- }
418
- }
419
- finally {
420
- yield tracker.cleanup(rootLocator.page());
421
- }
422
- return results;
318
+ return (0, tableIteration_1.runMap)({
319
+ getRowLocators: () => resolve(config.rowSelector, rootLocator),
320
+ getMap: () => tableMapper.getMapSync(),
321
+ advancePage: _advancePage,
322
+ makeSmartRow: (loc, map, idx, pageIdx) => _makeSmart(loc, map, idx, pageIdx),
323
+ createSmartRowArray: smartRowArray_1.createSmartRowArray,
324
+ config,
325
+ getPage: () => rootLocator.page(),
326
+ }, callback, options);
423
327
  }),
424
328
  filter: (predicate_1, ...args_1) => __awaiter(void 0, [predicate_1, ...args_1], void 0, function* (predicate, options = {}) {
425
- var _a, _b, _c, _d;
426
329
  yield _autoInit();
427
- const map = tableMapper.getMapSync();
428
- const effectiveMaxPages = (_a = options.maxPages) !== null && _a !== void 0 ? _a : config.maxPages;
429
- const dedupeStrategy = (_b = options.dedupe) !== null && _b !== void 0 ? _b : config.strategies.dedupe;
430
- const dedupeKeys = dedupeStrategy ? new Set() : null;
431
- const parallel = (_c = options.parallel) !== null && _c !== void 0 ? _c : false;
432
- const useBulk = (_d = options.useBulkPagination) !== null && _d !== void 0 ? _d : false;
433
- const tracker = new elementTracker_1.ElementTracker('filter');
434
- const matched = [];
435
- try {
436
- let rowIndex = 0;
437
- let stopped = false;
438
- let pagesScanned = 1;
439
- const stop = () => { stopped = true; };
440
- while (!stopped) {
441
- const rowLocators = resolve(config.rowSelector, rootLocator);
442
- const newIndices = yield tracker.getUnseenIndices(rowLocators);
443
- const pageRows = yield rowLocators.all();
444
- const smartRows = newIndices.map((idx, i) => _makeSmart(pageRows[idx], map, rowIndex + i, pagesScanned - 1));
445
- if (parallel) {
446
- const flags = yield Promise.all(smartRows.map((row) => __awaiter(void 0, void 0, void 0, function* () {
447
- if (dedupeKeys) {
448
- const key = yield dedupeStrategy(row);
449
- if (dedupeKeys.has(key))
450
- return false;
451
- dedupeKeys.add(key);
452
- }
453
- return predicate({ row, rowIndex: row.rowIndex, stop });
454
- })));
455
- smartRows.forEach((row, i) => { if (flags[i])
456
- matched.push(row); });
457
- }
458
- else {
459
- for (const row of smartRows) {
460
- if (stopped)
461
- break;
462
- if (dedupeKeys) {
463
- const key = yield dedupeStrategy(row);
464
- if (dedupeKeys.has(key))
465
- continue;
466
- dedupeKeys.add(key);
467
- }
468
- if (yield predicate({ row, rowIndex: row.rowIndex, stop })) {
469
- matched.push(row);
470
- }
471
- }
472
- }
473
- rowIndex += smartRows.length;
474
- if (stopped || pagesScanned >= effectiveMaxPages)
475
- break;
476
- if (!(yield _advancePage(useBulk)))
477
- break;
478
- pagesScanned++;
479
- }
480
- }
481
- finally {
482
- yield tracker.cleanup(rootLocator.page());
483
- }
484
- return (0, smartRowArray_1.createSmartRowArray)(matched);
330
+ return (0, tableIteration_1.runFilter)({
331
+ getRowLocators: () => resolve(config.rowSelector, rootLocator),
332
+ getMap: () => tableMapper.getMapSync(),
333
+ advancePage: _advancePage,
334
+ makeSmartRow: (loc, map, idx, pageIdx) => _makeSmart(loc, map, idx, pageIdx),
335
+ createSmartRowArray: smartRowArray_1.createSmartRowArray,
336
+ config,
337
+ getPage: () => rootLocator.page(),
338
+ }, predicate, options);
485
339
  }),
486
340
  generateConfig: () => __awaiter(void 0, void 0, void 0, function* () {
487
341
  const html = yield _getCleanHtml(rootLocator);
@@ -494,6 +348,15 @@ const useTable = (rootLocator, configOptions = {}) => {
494
348
  return result.generateConfig();
495
349
  }),
496
350
  };
351
+ createStrategyContext = () => ({
352
+ root: rootLocator,
353
+ config,
354
+ page: rootLocator.page(),
355
+ resolve,
356
+ getHeaderCell: result.getHeaderCell,
357
+ getHeaders: result.getHeaders,
358
+ scrollToColumn: result.scrollToColumn,
359
+ });
497
360
  finalTable = result;
498
361
  return result;
499
362
  };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Internal symbol used to mark a SmartRow as a "sentinel" (row not found).
3
+ * Use SmartRow.wasFound() to detect; do not rely on this symbol in user code.
4
+ */
5
+ export declare const SENTINEL_ROW: unique symbol;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SENTINEL_ROW = void 0;
4
+ /**
5
+ * Internal symbol used to mark a SmartRow as a "sentinel" (row not found).
6
+ * Use SmartRow.wasFound() to detect; do not rely on this symbol in user code.
7
+ */
8
+ exports.SENTINEL_ROW = Symbol.for('playwright-smart-table.sentinelRow');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rickcedwhat/playwright-smart-table",
3
- "version": "6.7.4",
3
+ "version": "6.7.5",
4
4
  "description": "Smart, column-aware table interactions for Playwright",
5
5
  "author": "Cedrick Catalan",
6
6
  "license": "MIT",