@blackglory/match 0.3.6 → 0.4.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 (97) hide show
  1. package/README.md +86 -36
  2. package/lib/index.d.ts +17 -17
  3. package/lib/index.js +17 -37
  4. package/lib/index.js.map +1 -1
  5. package/lib/match-element.d.ts +3 -4
  6. package/lib/match-element.js +9 -11
  7. package/lib/match-element.js.map +1 -1
  8. package/lib/match.d.ts +3 -4
  9. package/lib/match.js +9 -11
  10. package/lib/match.js.map +1 -1
  11. package/lib/matchers/any-of.d.ts +1 -1
  12. package/lib/matchers/any-of.js +1 -5
  13. package/lib/matchers/any-of.js.map +1 -1
  14. package/lib/matchers/child-nodes.d.ts +1 -1
  15. package/lib/matchers/child-nodes.js +10 -12
  16. package/lib/matchers/child-nodes.js.map +1 -1
  17. package/lib/matchers/children.d.ts +1 -1
  18. package/lib/matchers/children.js +10 -12
  19. package/lib/matchers/children.js.map +1 -1
  20. package/lib/matchers/css.d.ts +1 -1
  21. package/lib/matchers/css.js +5 -9
  22. package/lib/matchers/css.js.map +1 -1
  23. package/lib/matchers/element.d.ts +1 -1
  24. package/lib/matchers/element.js +11 -15
  25. package/lib/matchers/element.js.map +1 -1
  26. package/lib/matchers/multiple.d.ts +1 -1
  27. package/lib/matchers/multiple.js +14 -17
  28. package/lib/matchers/multiple.js.map +1 -1
  29. package/lib/matchers/node.d.ts +1 -1
  30. package/lib/matchers/node.js +9 -13
  31. package/lib/matchers/node.js.map +1 -1
  32. package/lib/matchers/optional.d.ts +1 -1
  33. package/lib/matchers/optional.js +3 -7
  34. package/lib/matchers/optional.js.map +1 -1
  35. package/lib/matchers/repeat.d.ts +1 -1
  36. package/lib/matchers/repeat.js +6 -10
  37. package/lib/matchers/repeat.js.map +1 -1
  38. package/lib/matchers/tap.d.ts +1 -1
  39. package/lib/matchers/tap.js +1 -5
  40. package/lib/matchers/tap.js.map +1 -1
  41. package/lib/matchers/text-content-equals.d.ts +1 -1
  42. package/lib/matchers/text-content-equals.js +3 -7
  43. package/lib/matchers/text-content-equals.js.map +1 -1
  44. package/lib/matchers/text-content-includes.d.ts +1 -1
  45. package/lib/matchers/text-content-includes.js +3 -7
  46. package/lib/matchers/text-content-includes.js.map +1 -1
  47. package/lib/matchers/text-content-matches.d.ts +1 -1
  48. package/lib/matchers/text-content-matches.js +3 -7
  49. package/lib/matchers/text-content-matches.js.map +1 -1
  50. package/lib/matchers/text-node.d.ts +1 -1
  51. package/lib/matchers/text-node.js +10 -14
  52. package/lib/matchers/text-node.js.map +1 -1
  53. package/lib/matchers/xpath.d.ts +1 -1
  54. package/lib/matchers/xpath.js +8 -12
  55. package/lib/matchers/xpath.js.map +1 -1
  56. package/lib/types.d.ts +7 -6
  57. package/lib/types.js +1 -2
  58. package/lib/utils/match-multiple.d.ts +4 -1
  59. package/lib/utils/match-multiple.js +6 -7
  60. package/lib/utils/match-multiple.js.map +1 -1
  61. package/lib/utils/match-one-by-one.d.ts +1 -1
  62. package/lib/utils/match-one-by-one.js +10 -10
  63. package/lib/utils/match-one-by-one.js.map +1 -1
  64. package/lib/utils/merge-in-place.d.ts +2 -5
  65. package/lib/utils/merge-in-place.js +5 -9
  66. package/lib/utils/merge-in-place.js.map +1 -1
  67. package/lib/utils/next-element-sibling.js +2 -6
  68. package/lib/utils/next-element-sibling.js.map +1 -1
  69. package/lib/utils/next-sibling.js +2 -6
  70. package/lib/utils/next-sibling.js.map +1 -1
  71. package/package.json +30 -29
  72. package/src/index.ts +17 -17
  73. package/src/match-element.ts +9 -5
  74. package/src/match.ts +9 -5
  75. package/src/matchers/any-of.ts +1 -1
  76. package/src/matchers/child-nodes.ts +6 -5
  77. package/src/matchers/children.ts +6 -5
  78. package/src/matchers/css.ts +4 -4
  79. package/src/matchers/element.ts +42 -17
  80. package/src/matchers/multiple.ts +3 -3
  81. package/src/matchers/node.ts +35 -13
  82. package/src/matchers/optional.ts +5 -3
  83. package/src/matchers/repeat.ts +3 -3
  84. package/src/matchers/tap.ts +1 -1
  85. package/src/matchers/text-content-equals.ts +2 -2
  86. package/src/matchers/text-content-includes.ts +2 -2
  87. package/src/matchers/text-content-matches.ts +2 -2
  88. package/src/matchers/text-node.ts +13 -9
  89. package/src/matchers/xpath.ts +10 -10
  90. package/src/types.ts +7 -4
  91. package/src/utils/match-multiple.ts +1 -1
  92. package/src/utils/match-one-by-one.ts +3 -3
  93. package/src/utils/merge-in-place.ts +3 -3
  94. package/lib/utils/concat.d.ts +0 -1
  95. package/lib/utils/concat.js +0 -14
  96. package/lib/utils/concat.js.map +0 -1
  97. package/src/utils/concat.ts +0 -9
@@ -1,15 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.matchOneByOne = void 0;
4
- const types_1 = require("@blackglory/types");
5
- function matchOneByOne(context, source, ...matchers) {
6
- if (matchers.length === 0)
1
+ import { isBoolean, isNumber, isIterable, isEmptyArray } from '@blackglory/prelude';
2
+ export function matchOneByOne(context, source, ...matchers) {
3
+ if (isEmptyArray(matchers))
7
4
  return true;
8
5
  if (!source)
9
6
  return false;
10
7
  const [matcher, ...otherMatchers] = matchers;
11
8
  const result = Reflect.apply(matcher, context, [source]);
12
- if ((0, types_1.isBoolean)(result)) {
9
+ // TerminalMatcher
10
+ if (isBoolean(result)) {
13
11
  if (result) {
14
12
  const nextNode = context.next(source);
15
13
  return matchOneByOne(context, nextNode, ...otherMatchers);
@@ -18,21 +16,23 @@ function matchOneByOne(context, source, ...matchers) {
18
16
  return false;
19
17
  }
20
18
  }
21
- if ((0, types_1.isNumber)(result)) {
19
+ // 此处一定是成功匹配, 因为SkipMatcher在失败时会返回false.
20
+ if (isNumber(result)) {
22
21
  const distance = result;
23
22
  const nextNode = context.next(source, distance);
24
23
  return matchOneByOne(context, nextNode, ...otherMatchers);
25
24
  }
26
- if ((0, types_1.isIterable)(result)) {
25
+ // SkipMatcher返回Iterable意味着存在多种可能性, 可能出现失败回溯.
26
+ if (isIterable(result)) {
27
27
  for (const distance of result) {
28
28
  const nextNode = context.next(source, distance);
29
29
  if (matchOneByOne(context, nextNode, ...otherMatchers)) {
30
30
  return true;
31
31
  }
32
32
  }
33
+ // 尝试了所有可能性, 未发现可以匹配的结果
33
34
  return false;
34
35
  }
35
36
  throw new Error('Unknown return value');
36
37
  }
37
- exports.matchOneByOne = matchOneByOne;
38
38
  //# sourceMappingURL=match-one-by-one.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"match-one-by-one.js","sourceRoot":"","sources":["../../src/utils/match-one-by-one.ts"],"names":[],"mappings":";;;AACA,6CAAmE;AAEnE,SAAgB,aAAa,CAC3B,OAAyB,EACzB,MAAgB,EAChB,GAAG,QAA4B;IAE/B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEzB,MAAM,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,GAAG,QAAQ,CAAA;IAE5C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAA+B,CAAA;IAGtF,IAAI,IAAA,iBAAS,EAAC,MAAM,CAAC,EAAE;QACrB,IAAI,MAAM,EAAE;YACV,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAa,CAAA;YACjD,OAAO,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,CAAA;SAC1D;aAAM;YACL,OAAO,KAAK,CAAA;SACb;KACF;IAGD,IAAI,IAAA,gBAAQ,EAAC,MAAM,CAAC,EAAE;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAA;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAa,CAAA;QAC3D,OAAO,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,CAAA;KAC1D;IAGD,IAAI,IAAA,kBAAU,EAAC,MAAM,CAAC,EAAE;QACtB,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE;YAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAa,CAAA;YAC3D,IAAI,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,EAAE;gBACtD,OAAO,IAAI,CAAA;aACZ;SACF;QAGD,OAAO,KAAK,CAAA;KACb;IAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;AACzC,CAAC;AA3CD,sCA2CC"}
1
+ {"version":3,"file":"match-one-by-one.js","sourceRoot":"","sources":["../../src/utils/match-one-by-one.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEnF,MAAM,UAAU,aAAa,CAC3B,OAAyB,EACzB,MAAgB,EAChB,GAAG,QAA4B;IAE/B,IAAI,YAAY,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEzB,MAAM,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,GAAG,QAAQ,CAAA;IAE5C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAA+B,CAAA;IAEtF,kBAAkB;IAClB,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAa,CAAA;YACjD,OAAO,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,CAAA;QAC3D,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,MAAM,CAAA;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAa,CAAA;QAC3D,OAAO,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,CAAA;IAC3D,CAAC;IAED,6CAA6C;IAC7C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAa,CAAA;YAC3D,IAAI,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC;gBACvD,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;AACzC,CAAC"}
@@ -1,5 +1,2 @@
1
- export declare function mergeInPlace<T>(target: {
2
- [key: string]: T | T[];
3
- }, source: {
4
- [key: string]: T | T[];
5
- }): void;
1
+ import { Arrayable } from '@blackglory/prelude';
2
+ export declare function mergeInPlace<T>(target: Record<string, Arrayable<T>>, source: Record<string, Arrayable<T>>): void;
@@ -1,12 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mergeInPlace = void 0;
4
- const types_1 = require("@blackglory/types");
5
- function mergeInPlace(target, source) {
1
+ import { isArray } from '@blackglory/prelude';
2
+ export function mergeInPlace(target, source) {
6
3
  for (const [key, value] of Object.entries(source)) {
7
4
  if (target[key]) {
8
- if ((0, types_1.isArray)(target[key])) {
9
- if ((0, types_1.isArray)(value)) {
5
+ if (isArray(target[key])) {
6
+ if (isArray(value)) {
10
7
  target[key] = [...target[key], ...value];
11
8
  }
12
9
  else {
@@ -14,7 +11,7 @@ function mergeInPlace(target, source) {
14
11
  }
15
12
  }
16
13
  else {
17
- if ((0, types_1.isArray)(value)) {
14
+ if (isArray(value)) {
18
15
  target[key] = [target[key], ...value];
19
16
  }
20
17
  else {
@@ -27,5 +24,4 @@ function mergeInPlace(target, source) {
27
24
  }
28
25
  }
29
26
  }
30
- exports.mergeInPlace = mergeInPlace;
31
27
  //# sourceMappingURL=merge-in-place.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge-in-place.js","sourceRoot":"","sources":["../../src/utils/merge-in-place.ts"],"names":[],"mappings":";;;AAAA,6CAA2C;AAE3C,SAAgB,YAAY,CAC1B,MAAkC,EAClC,MAAkC;IAElC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACjD,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE;YACf,IAAI,IAAA,eAAO,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;gBACxB,IAAI,IAAA,eAAO,EAAC,KAAK,CAAC,EAAE;oBAClB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAQ,EAAE,GAAG,KAAK,CAAC,CAAA;iBAChD;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAQ,EAAE,KAAK,CAAC,CAAA;iBAC7C;aACF;iBAAM;gBACL,IAAI,IAAA,eAAO,EAAC,KAAK,CAAC,EAAE;oBAClB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAM,EAAE,GAAG,KAAK,CAAC,CAAA;iBAC3C;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAM,EAAE,KAAK,CAAC,CAAA;iBACxC;aACF;SACF;aAAM;YACL,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;SACpB;KACF;AACH,CAAC;AAvBD,oCAuBC"}
1
+ {"version":3,"file":"merge-in-place.js","sourceRoot":"","sources":["../../src/utils/merge-in-place.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAExD,MAAM,UAAU,YAAY,CAC1B,MAAoC,EACpC,MAAoC;IAEpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAChB,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACzB,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAQ,EAAE,GAAG,KAAK,CAAC,CAAA;gBACjD,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAQ,EAAE,KAAK,CAAC,CAAA;gBAC9C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAM,EAAE,GAAG,KAAK,CAAC,CAAA;gBAC5C,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAM,EAAE,KAAK,CAAC,CAAA;gBACzC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACrB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,11 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.nextElementSibling = void 0;
4
- const ExtraDOM = require("extra-dom");
5
- function nextElementSibling(node, distance = 1) {
1
+ import * as ExtraDOM from 'extra-dom';
2
+ export function nextElementSibling(node, distance = 1) {
6
3
  if (distance === 0)
7
4
  return node;
8
5
  return ExtraDOM.nextElementSibling(node, distance);
9
6
  }
10
- exports.nextElementSibling = nextElementSibling;
11
7
  //# sourceMappingURL=next-element-sibling.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"next-element-sibling.js","sourceRoot":"","sources":["../../src/utils/next-element-sibling.ts"],"names":[],"mappings":";;;AAAA,sCAAqC;AAErC,SAAgB,kBAAkB,CAChC,IAAU,EACV,WAAmB,CAAC;IAEpB,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAE/B,OAAO,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AACpD,CAAC;AAPD,gDAOC"}
1
+ {"version":3,"file":"next-element-sibling.js","sourceRoot":"","sources":["../../src/utils/next-element-sibling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;AAErC,MAAM,UAAU,kBAAkB,CAChC,IAAU,EACV,WAAmB,CAAC;IAEpB,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAE/B,OAAO,QAAQ,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AACpD,CAAC"}
@@ -1,11 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.nextSibling = void 0;
4
- const ExtraDOM = require("extra-dom");
5
- function nextSibling(node, distance = 1) {
1
+ import * as ExtraDOM from 'extra-dom';
2
+ export function nextSibling(node, distance = 1) {
6
3
  if (distance === 0)
7
4
  return node;
8
5
  return ExtraDOM.nextSibling(node, distance);
9
6
  }
10
- exports.nextSibling = nextSibling;
11
7
  //# sourceMappingURL=next-sibling.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"next-sibling.js","sourceRoot":"","sources":["../../src/utils/next-sibling.ts"],"names":[],"mappings":";;;AAAA,sCAAqC;AAErC,SAAgB,WAAW,CAAC,IAAU,EAAE,WAAmB,CAAC;IAC1D,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAE/B,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AAC7C,CAAC;AAJD,kCAIC"}
1
+ {"version":3,"file":"next-sibling.js","sourceRoot":"","sources":["../../src/utils/next-sibling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;AAErC,MAAM,UAAU,WAAW,CAAC,IAAU,EAAE,WAAmB,CAAC;IAC1D,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAE/B,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AAC7C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blackglory/match",
3
- "version": "0.3.6",
3
+ "version": "0.4.1",
4
4
  "description": "A module for matching nodes from pages",
5
5
  "keywords": [
6
6
  "query",
@@ -11,53 +11,54 @@
11
11
  "lib",
12
12
  "src"
13
13
  ],
14
+ "type": "module",
14
15
  "main": "lib/index.js",
15
16
  "types": "lib/index.d.ts",
17
+ "sideEffects": false,
18
+ "engines": {
19
+ "node": ">=22"
20
+ },
16
21
  "repository": "git@github.com:BlackGlory/match.git",
17
22
  "author": "BlackGlory <woshenmedoubuzhidao@blackglory.me>",
18
23
  "license": "MIT",
19
- "sideEffects": false,
20
24
  "scripts": {
25
+ "prepare": "ts-patch install -s",
21
26
  "lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src __tests__",
22
- "test": "jest --config jest.config.js",
23
- "test:coverage": "jest --coverage --config jest.config.js",
24
- "prepublishOnly": "run-s clean build",
27
+ "test": "vitest --run",
28
+ "prepublishOnly": "run-s prepare clean build",
25
29
  "clean": "rimraf lib",
26
- "build": "run-s build:*",
27
- "build:compile": "tsc --project tsconfig.build.json --module commonjs --target es2018 --outDir lib",
28
- "build:patch": "tscpaths -p tsconfig.build.json -s ./src -o ./lib",
30
+ "build": "tsc --project tsconfig.build.json",
29
31
  "release": "standard-version"
30
32
  },
31
33
  "husky": {
32
34
  "hooks": {
33
- "pre-commit": "run-s lint build test",
35
+ "pre-commit": "run-s prepare lint build test",
34
36
  "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
35
37
  }
36
38
  },
37
39
  "devDependencies": {
38
- "@commitlint/cli": "^15.0.0",
39
- "@commitlint/config-conventional": "^15.0.0",
40
- "@types/jest": "^27.0.3",
41
- "@types/jsdom": "^16.2.13",
42
- "@typescript-eslint/eslint-plugin": "^5.6.0",
43
- "@typescript-eslint/parser": "^5.6.0",
44
- "eslint": "^8.4.1",
40
+ "@commitlint/cli": "^20.3.1",
41
+ "@commitlint/config-conventional": "^20.3.1",
42
+ "@eslint/js": "^9.39.2",
43
+ "@types/jsdom": "^27.0.0",
44
+ "eslint": "^9.39.2",
45
45
  "husky": "^4.3.8",
46
- "iterable-operator": "^0.14.4",
47
- "jest": "^27.4.4",
48
- "jsdom": "^19.0.0",
46
+ "jsdom": "^27.4.0",
49
47
  "npm-run-all": "^4.1.5",
50
- "rimraf": "^3.0.2",
51
- "standard-version": "^9.3.2",
52
- "ts-jest": "^27.1.1",
53
- "tscpaths": "^0.0.9",
54
- "tslib": "^2.3.1",
55
- "typescript": "^4.5.3"
48
+ "rimraf": "^6.1.2",
49
+ "standard-version": "^9.5.0",
50
+ "ts-patch": "^3.3.0",
51
+ "tslib": "^2.8.1",
52
+ "typescript": "^5.9.3",
53
+ "typescript-eslint": "^8.53.0",
54
+ "typescript-transform-paths": "^3.5.6",
55
+ "vite-tsconfig-paths": "^6.0.4",
56
+ "vitest": "^4.0.17"
56
57
  },
57
58
  "dependencies": {
58
- "@blackglory/errors": "^1.1.2",
59
- "@blackglory/types": "^0.5.2",
60
- "extra-dom": "^0.4.4",
61
- "extra-generator": "^0.2.15"
59
+ "@blackglory/prelude": "^0.4.0",
60
+ "extra-dom": "^0.7.0",
61
+ "extra-generator": "^0.5.9",
62
+ "extra-tags": "^0.5.4"
62
63
  }
63
64
  }
package/src/index.ts CHANGED
@@ -1,18 +1,18 @@
1
- export { match } from './match'
2
- export { matchElement } from './match-element'
1
+ export { match } from './match.js'
2
+ export { matchElement } from './match-element.js'
3
3
 
4
- export { anyOf } from '@matchers/any-of'
5
- export { childNodes } from '@matchers/child-nodes'
6
- export { children } from '@matchers/children'
7
- export { css } from '@matchers/css'
8
- export { element } from '@matchers/element'
9
- export { multiple } from '@matchers/multiple'
10
- export { node } from '@matchers/node'
11
- export { optional } from '@matchers/optional'
12
- export { repeat } from '@matchers/repeat'
13
- export { tap } from '@matchers/tap'
14
- export { textContentEquals } from '@matchers/text-content-equals'
15
- export { textContentIncludes } from '@matchers/text-content-includes'
16
- export { textContentMatches } from '@matchers/text-content-matches'
17
- export { textNode } from '@matchers/text-node'
18
- export { xpath } from '@matchers/xpath'
4
+ export { anyOf } from '@matchers/any-of.js'
5
+ export { childNodes } from '@matchers/child-nodes.js'
6
+ export { children } from '@matchers/children.js'
7
+ export { css } from '@matchers/css.js'
8
+ export { element } from '@matchers/element.js'
9
+ export { multiple } from '@matchers/multiple.js'
10
+ export { node } from '@matchers/node.js'
11
+ export { optional } from '@matchers/optional.js'
12
+ export { repeat } from '@matchers/repeat.js'
13
+ export { tap } from '@matchers/tap.js'
14
+ export { textContentEquals } from '@matchers/text-content-equals.js'
15
+ export { textContentIncludes } from '@matchers/text-content-includes.js'
16
+ export { textContentMatches } from '@matchers/text-content-matches.js'
17
+ export { textNode } from '@matchers/text-node.js'
18
+ export { xpath } from '@matchers/xpath.js'
@@ -1,14 +1,18 @@
1
1
  import { isDocument } from 'extra-dom'
2
- import { IMatcher, IContext } from './types'
3
- import { matchOneByOne } from '@utils/match-one-by-one'
4
- import { nextElementSibling } from '@utils/next-element-sibling'
2
+ import { IMatcher, IContext } from './types.js'
3
+ import { matchOneByOne } from '@utils/match-one-by-one.js'
4
+ import { nextElementSibling } from '@utils/next-element-sibling.js'
5
+ import { Arrayable } from '@blackglory/prelude'
5
6
 
6
7
  export function matchElement(
7
8
  this: void | Document
8
9
  , element: Element
9
10
  , ...matchers: Array<IMatcher<Element>>
10
- ): { [name: string]: Node | Node[] } | null {
11
- const document = isDocument(this) ? this : globalThis.document
11
+ ): Record<string, Arrayable<Node>> | null {
12
+ const document = isDocument(this)
13
+ ? this
14
+ : globalThis.document
15
+
12
16
  const context: IContext = {
13
17
  document
14
18
  , collection: {}
package/src/match.ts CHANGED
@@ -1,14 +1,18 @@
1
1
  import { isDocument } from 'extra-dom'
2
- import { IMatcher, IContext } from './types'
3
- import { matchOneByOne } from '@utils/match-one-by-one'
4
- import { nextSibling } from '@utils/next-sibling'
2
+ import { IMatcher, IContext } from './types.js'
3
+ import { matchOneByOne } from '@utils/match-one-by-one.js'
4
+ import { nextSibling } from '@utils/next-sibling.js'
5
+ import { Arrayable } from '@blackglory/prelude'
5
6
 
6
7
  export function match(
7
8
  this: void | Document
8
9
  , node: Node
9
10
  , ...matchers: Array<IMatcher<Node>>
10
- ): { [name: string]: Node | Node[] } | null {
11
- const document = isDocument(this) ? this : globalThis.document
11
+ ): Record<string, Arrayable<Node>> | null {
12
+ const document = isDocument(this)
13
+ ? this
14
+ : globalThis.document
15
+
12
16
  const context: IContext = {
13
17
  document
14
18
  , collection: {}
@@ -1,4 +1,4 @@
1
- import { ITerminalMatcher, INestedMatcher, IReadonlyContext } from '@src/types'
1
+ import { ITerminalMatcher, INestedMatcher, IReadonlyContext } from '@src/types.js'
2
2
 
3
3
  export function anyOf<T extends Node>(
4
4
  ...matchers: [
@@ -1,12 +1,13 @@
1
- import { INestedMatcher, IMatcher, IReadonlyContext } from '@src/types'
2
- import { matchOneByOne } from '@utils/match-one-by-one'
3
- import { mergeInPlace } from '@utils/merge-in-place'
4
- import { nextSibling } from '@utils/next-sibling'
1
+ import { isEmptyArray } from '@blackglory/prelude'
2
+ import { INestedMatcher, IMatcher, IReadonlyContext } from '@src/types.js'
3
+ import { matchOneByOne } from '@utils/match-one-by-one.js'
4
+ import { mergeInPlace } from '@utils/merge-in-place.js'
5
+ import { nextSibling } from '@utils/next-sibling.js'
5
6
 
6
7
  export function childNodes(...matchers: Array<IMatcher<Node>>): INestedMatcher<Node> {
7
8
  return function (this: IReadonlyContext, node: Node) {
8
9
  // 空matchers意味着"childNodes应该为空".
9
- if (matchers.length === 0) {
10
+ if (isEmptyArray(matchers)) {
10
11
  return node.childNodes.length === 0
11
12
  }
12
13
 
@@ -1,14 +1,15 @@
1
- import { IMatcher, INestedMatcher, IReadonlyContext } from '@src/types'
2
- import { matchOneByOne } from '@utils/match-one-by-one'
3
- import { mergeInPlace } from '@utils/merge-in-place'
4
- import { nextElementSibling } from '@utils/next-element-sibling'
1
+ import { isEmptyArray } from '@blackglory/prelude'
2
+ import { IMatcher, INestedMatcher, IReadonlyContext } from '@src/types.js'
3
+ import { matchOneByOne } from '@utils/match-one-by-one.js'
4
+ import { mergeInPlace } from '@utils/merge-in-place.js'
5
+ import { nextElementSibling } from '@utils/next-element-sibling.js'
5
6
 
6
7
  export function children(
7
8
  ...matchers: Array<IMatcher<Element>>
8
9
  ): INestedMatcher<Element> {
9
10
  return function (this: IReadonlyContext, element: Element) {
10
11
  // 空matchers意味着"children应该为空".
11
- if (matchers.length === 0) {
12
+ if (isEmptyArray(matchers)) {
12
13
  return element.children.length === 0
13
14
  }
14
15
 
@@ -1,6 +1,6 @@
1
- import { concat } from '@utils/concat'
2
- import { ITerminalMatcher } from '@src/types'
3
- import { isString } from '@blackglory/types'
1
+ import { concat } from 'extra-tags'
2
+ import { ITerminalMatcher } from '@src/types.js'
3
+ import { isString } from '@blackglory/prelude'
4
4
 
5
5
  export function css(
6
6
  strings: TemplateStringsArray
@@ -17,7 +17,7 @@ export function css(...args:
17
17
  return (element: Element) => element.matches(selector)
18
18
  } else {
19
19
  const [strings, ...values] = args
20
- const selector = concat(strings, values).join('')
20
+ const selector = concat(strings, ...values)
21
21
 
22
22
  return css(selector)
23
23
  }
@@ -1,33 +1,53 @@
1
1
  import { isntElement } from 'extra-dom'
2
- import { INestedMatcher, ITerminalMatcher, IReadonlyContext } from '@src/types'
3
- import { isArray, isString } from '@blackglory/types'
4
- import { concat } from '@utils/concat'
5
- import { mergeInPlace } from '@utils/merge-in-place'
2
+ import { INestedMatcher, ITerminalMatcher, IReadonlyContext } from '@src/types.js'
3
+ import { isArray, isEmptyArray, isString } from '@blackglory/prelude'
4
+ import { concat } from 'extra-tags'
5
+ import { mergeInPlace } from '@utils/merge-in-place.js'
6
6
 
7
7
  export function element(
8
8
  strings: TemplateStringsArray
9
9
  , ...values: string[]
10
- ): (...matchers: Array<INestedMatcher<Element> | ITerminalMatcher<Element>>) => INestedMatcher<Node>
11
- export function element(name: string, ...matchers: Array<INestedMatcher<Element>>):
12
- INestedMatcher<Node>
13
- export function element(...matchers: Array<INestedMatcher<Element>>):
14
- INestedMatcher<Node>
10
+ ): (
11
+ ...matchers: Array<
12
+ | INestedMatcher<Element>
13
+ | ITerminalMatcher<Element>
14
+ >
15
+ ) => INestedMatcher<Node>
16
+ export function element(
17
+ name: string
18
+ , ...matchers: Array<INestedMatcher<Element>>
19
+ ): INestedMatcher<Node>
20
+ export function element(
21
+ ...matchers: Array<INestedMatcher<Element>>
22
+ ): INestedMatcher<Node>
15
23
  export function element(...args:
16
24
  | [strings: TemplateStringsArray, ...values: string[]]
17
25
  | [name: string, ...matchers: Array<INestedMatcher<Element> | ITerminalMatcher<Element>>]
18
26
  | [...matchers: Array<INestedMatcher<Element> | ITerminalMatcher<Element>>]
19
27
  ) {
20
28
  if (isArray(args[0])) {
21
- const [strings, ...values] =
22
- args as [strings: TemplateStringsArray, ...values: string[]]
23
- const name = concat(strings, values).join('')
29
+ const [strings, ...values] = args as [
30
+ strings: TemplateStringsArray
31
+ , ...values: string[]
32
+ ]
33
+ const name = concat(strings, ...values)
24
34
 
25
- return (...matchers: Array<INestedMatcher<Element> | ITerminalMatcher<Element>>) => element(name, ...matchers)
35
+ return (
36
+ ...matchers: Array<
37
+ | INestedMatcher<Element>
38
+ | ITerminalMatcher<Element>
39
+ >
40
+ ) => element(name, ...matchers)
26
41
  }
27
42
 
28
43
  if (isString(args[0])) {
29
- const [name, ...matchers] =
30
- args as [name: string, ...matchers: Array<INestedMatcher<Element> | ITerminalMatcher<Element>>]
44
+ const [name, ...matchers] = args as [
45
+ name: string
46
+ , ...matchers: Array<
47
+ | INestedMatcher<Element>
48
+ | ITerminalMatcher<Element>
49
+ >
50
+ ]
31
51
 
32
52
  return function (this: IReadonlyContext, _element: Element) {
33
53
  const result = element(...matchers).call(this, _element)
@@ -38,11 +58,16 @@ export function element(...args:
38
58
  }
39
59
  }
40
60
 
41
- const [...matchers] = args as [...matchers: Array<INestedMatcher<Element> | ITerminalMatcher<Element>>]
61
+ const [...matchers] = args as [
62
+ ...matchers: Array<
63
+ | INestedMatcher<Element>
64
+ | ITerminalMatcher<Element>
65
+ >
66
+ ]
42
67
 
43
68
  return function (this: IReadonlyContext, element: Element) {
44
69
  if (isntElement(element)) return false
45
- if (matchers.length === 0) return true
70
+ if (isEmptyArray(matchers)) return true
46
71
 
47
72
  return matchers.every(match => match.call(this, element))
48
73
  }
@@ -1,7 +1,7 @@
1
- import { INestedMatcher, ITerminalMatcher, ISkipMatcher, IReadonlyContext } from '@src/types'
1
+ import { INestedMatcher, ITerminalMatcher, ISkipMatcher, IReadonlyContext } from '@src/types.js'
2
2
  import { countup } from 'extra-generator'
3
- import { assert } from '@blackglory/errors'
4
- import { matchMultiple } from '@utils/match-multiple'
3
+ import { assert } from '@blackglory/prelude'
4
+ import { matchMultiple } from '@utils/match-multiple.js'
5
5
 
6
6
  export enum Range {
7
7
  Min = 0
@@ -1,12 +1,17 @@
1
- import { INestedMatcher, ITerminalMatcher, IReadonlyContext } from '@src/types'
2
- import { isArray, isString } from '@blackglory/types'
3
- import { concat } from '@utils/concat'
4
- import { mergeInPlace } from '@utils/merge-in-place'
1
+ import { INestedMatcher, ITerminalMatcher, IReadonlyContext } from '@src/types.js'
2
+ import { isArray, isEmptyArray, isString } from '@blackglory/prelude'
3
+ import { concat } from 'extra-tags'
4
+ import { mergeInPlace } from '@utils/merge-in-place.js'
5
5
 
6
6
  export function node(
7
7
  strings: TemplateStringsArray
8
8
  , ...values: string[]
9
- ): (...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>) => INestedMatcher<Node>
9
+ ): (
10
+ ...matchers: Array<
11
+ | INestedMatcher<Node>
12
+ | ITerminalMatcher<Node>
13
+ >
14
+ ) => INestedMatcher<Node>
10
15
  export function node(
11
16
  name: string
12
17
  , ...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>
@@ -20,16 +25,28 @@ export function node(...args:
20
25
  | [...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>]
21
26
  ) {
22
27
  if (isArray(args[0])) {
23
- const [strings, ...values] =
24
- args as [strings: TemplateStringsArray, ...values: string[]]
25
- const name = concat(strings, values).join('')
28
+ const [strings, ...values] = args as [
29
+ strings: TemplateStringsArray
30
+ , ...values: string[]
31
+ ]
32
+ const name = concat(strings, ...values)
26
33
 
27
- return (...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>) => node(name, ...matchers)
34
+ return (
35
+ ...matchers: Array<
36
+ | INestedMatcher<Node>
37
+ | ITerminalMatcher<Node>
38
+ >
39
+ ) => node(name, ...matchers)
28
40
  }
29
41
 
30
42
  if (isString(args[0])) {
31
- const [name, ...matchers] =
32
- args as [name: string, ...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>]
43
+ const [name, ...matchers] = args as [
44
+ name: string
45
+ , ...matchers: Array<
46
+ | INestedMatcher<Node>
47
+ | ITerminalMatcher<Node>
48
+ >
49
+ ]
33
50
 
34
51
  return function (this: IReadonlyContext, _node: Node) {
35
52
  const result = node(...matchers).call(this, _node)
@@ -40,10 +57,15 @@ export function node(...args:
40
57
  }
41
58
  }
42
59
 
43
- const [...matchers] = args as [...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>]
60
+ const [...matchers] = args as [
61
+ ...matchers: Array<
62
+ | INestedMatcher<Node>
63
+ | ITerminalMatcher<Node>
64
+ >
65
+ ]
44
66
 
45
67
  return function (this: IReadonlyContext, node: Node) {
46
- if (matchers.length === 0) return true
68
+ if (isEmptyArray(matchers)) return true
47
69
 
48
70
  return matchers.every(match => match.call(this, node))
49
71
  }
@@ -1,6 +1,8 @@
1
- import { INestedMatcher, ITerminalMatcher, ISkipMatcher } from '@src/types'
2
- import { multiple } from './multiple'
1
+ import { INestedMatcher, ITerminalMatcher, ISkipMatcher } from '@src/types.js'
2
+ import { multiple } from './multiple.js'
3
3
 
4
- export function optional<T extends Node>(matcher: INestedMatcher<T> | ITerminalMatcher<T>): ISkipMatcher<T> {
4
+ export function optional<T extends Node>(
5
+ matcher: INestedMatcher<T> | ITerminalMatcher<T>
6
+ ): ISkipMatcher<T> {
5
7
  return multiple([0, 1], matcher, { greedy: true })
6
8
  }
@@ -1,6 +1,6 @@
1
- import { INestedMatcher, ITerminalMatcher, ISkipMatcher, IReadonlyContext } from '@src/types'
2
- import { assert } from '@blackglory/errors'
3
- import { matchMultiple } from '@utils/match-multiple'
1
+ import { INestedMatcher, ITerminalMatcher, ISkipMatcher, IReadonlyContext } from '@src/types.js'
2
+ import { assert } from '@blackglory/prelude'
3
+ import { matchMultiple } from '@utils/match-multiple.js'
4
4
 
5
5
  export function repeat<T extends Node>(
6
6
  times: number
@@ -1,4 +1,4 @@
1
- import { IReadonlyContext, IMatcher } from '@src/types'
1
+ import { IReadonlyContext, IMatcher } from '@src/types.js'
2
2
 
3
3
  export function tap<T extends Node, U extends ReturnType<IMatcher<any>>>(
4
4
  matcher: (this: IReadonlyContext, node: T) => U
@@ -1,5 +1,5 @@
1
- import { ITerminalMatcher } from '@src/types'
2
- import { isNull } from '@blackglory/types'
1
+ import { ITerminalMatcher } from '@src/types.js'
2
+ import { isNull } from '@blackglory/prelude'
3
3
 
4
4
  interface ITextContentEqualsOptions {
5
5
  caseSensitive?: boolean
@@ -1,5 +1,5 @@
1
- import { ITerminalMatcher } from '@src/types'
2
- import { isNull } from '@blackglory/types'
1
+ import { ITerminalMatcher } from '@src/types.js'
2
+ import { isNull } from '@blackglory/prelude'
3
3
 
4
4
  interface ITextContentIncludesOptions {
5
5
  caseSensitive?: boolean
@@ -1,5 +1,5 @@
1
- import { ITerminalMatcher } from '@src/types'
2
- import { isNull } from '@blackglory/types'
1
+ import { ITerminalMatcher } from '@src/types.js'
2
+ import { isNull } from '@blackglory/prelude'
3
3
 
4
4
  interface ITextContentMatchesOptions {
5
5
  trim?: boolean