@pgpmjs/ast 0.7.1 → 0.9.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.
@@ -1,28 +1,34 @@
1
- function escapeRe(str) {
2
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3
- }
4
1
  /**
5
2
  * Rewrite change names in a pgpm.plan's content according to a rename map.
6
3
  * Textual and format-preserving: only the change-name token at the start of a
7
4
  * change line, plain (same-package) dependency refs inside `[...]`, and tag
8
5
  * lines' change field are rewritten; timestamps, planners, comments,
9
6
  * cross-package refs, and tag refs are untouched.
7
+ *
8
+ * Runs in a single linear pass: each line is scanned once and every
9
+ * whitespace/bracket-delimited token is looked up in the rename map directly,
10
+ * so the rewrite is O(content length) rather than O(lines × renames). A token
11
+ * qualifies when it is bounded on the left by start-of-line, whitespace or `[`
12
+ * and on the right by end-of-line, whitespace, `]` or `@` — which is exactly
13
+ * the change-name and plain-dependency positions. Cross-package refs
14
+ * (`pkg:change`) are left untouched because their change segment is preceded by
15
+ * `:`, and a trailing `@tag` suffix is preserved because the token ends at `@`.
10
16
  */
11
17
  export function renameInPlanContent(content, renames) {
12
- const froms = Array.from(renames.keys()).sort((a, b) => b.length - a.length);
18
+ if (renames.size === 0)
19
+ return content;
20
+ // One regex, compiled once per call (not per line or per rename).
21
+ const tokenRe = /(^|[\s\[])([^\s\[\]@]+)(?=$|[\s\]@])/g;
13
22
  return content
14
23
  .split('\n')
15
24
  .map(line => {
16
25
  const trimmed = line.trim();
17
26
  if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('%'))
18
27
  return line;
19
- let result = line;
20
- for (const from of froms) {
21
- const to = renames.get(from);
22
- const re = new RegExp(`(^|[\\s\\[])${escapeRe(from)}(?=$|[\\s\\]@])`, 'g');
23
- result = result.replace(re, `$1${to}`);
24
- }
25
- return result;
28
+ return line.replace(tokenRe, (match, pre, token) => {
29
+ const to = renames.get(token);
30
+ return to === undefined ? match : `${pre}${to}`;
31
+ });
26
32
  })
27
33
  .join('\n');
28
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/ast",
3
- "version": "0.7.1",
3
+ "version": "0.9.1",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM module AST — plan/control/SQL-header parsers and the lossless module read/write layer",
6
6
  "main": "index.js",
@@ -41,8 +41,8 @@
41
41
  "makage": "^0.3.0"
42
42
  },
43
43
  "dependencies": {
44
- "@pgpmjs/env": "^2.35.1",
45
- "@pgpmjs/types": "^2.43.1"
44
+ "@pgpmjs/env": "^2.37.0",
45
+ "@pgpmjs/types": "^2.45.0"
46
46
  },
47
- "gitHead": "37e83eb66e9d13d0d4d8ac3b36b5ebe394b84a43"
47
+ "gitHead": "d85911699e8a50a9fdfeb7506195442525c1f238"
48
48
  }
package/plan-rename.d.ts CHANGED
@@ -4,5 +4,14 @@
4
4
  * change line, plain (same-package) dependency refs inside `[...]`, and tag
5
5
  * lines' change field are rewritten; timestamps, planners, comments,
6
6
  * cross-package refs, and tag refs are untouched.
7
+ *
8
+ * Runs in a single linear pass: each line is scanned once and every
9
+ * whitespace/bracket-delimited token is looked up in the rename map directly,
10
+ * so the rewrite is O(content length) rather than O(lines × renames). A token
11
+ * qualifies when it is bounded on the left by start-of-line, whitespace or `[`
12
+ * and on the right by end-of-line, whitespace, `]` or `@` — which is exactly
13
+ * the change-name and plain-dependency positions. Cross-package refs
14
+ * (`pkg:change`) are left untouched because their change segment is preceded by
15
+ * `:`, and a trailing `@tag` suffix is preserved because the token ends at `@`.
7
16
  */
8
17
  export declare function renameInPlanContent(content: string, renames: Map<string, string>): string;
package/plan-rename.js CHANGED
@@ -1,31 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renameInPlanContent = renameInPlanContent;
4
- function escapeRe(str) {
5
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
6
- }
7
4
  /**
8
5
  * Rewrite change names in a pgpm.plan's content according to a rename map.
9
6
  * Textual and format-preserving: only the change-name token at the start of a
10
7
  * change line, plain (same-package) dependency refs inside `[...]`, and tag
11
8
  * lines' change field are rewritten; timestamps, planners, comments,
12
9
  * cross-package refs, and tag refs are untouched.
10
+ *
11
+ * Runs in a single linear pass: each line is scanned once and every
12
+ * whitespace/bracket-delimited token is looked up in the rename map directly,
13
+ * so the rewrite is O(content length) rather than O(lines × renames). A token
14
+ * qualifies when it is bounded on the left by start-of-line, whitespace or `[`
15
+ * and on the right by end-of-line, whitespace, `]` or `@` — which is exactly
16
+ * the change-name and plain-dependency positions. Cross-package refs
17
+ * (`pkg:change`) are left untouched because their change segment is preceded by
18
+ * `:`, and a trailing `@tag` suffix is preserved because the token ends at `@`.
13
19
  */
14
20
  function renameInPlanContent(content, renames) {
15
- const froms = Array.from(renames.keys()).sort((a, b) => b.length - a.length);
21
+ if (renames.size === 0)
22
+ return content;
23
+ // One regex, compiled once per call (not per line or per rename).
24
+ const tokenRe = /(^|[\s\[])([^\s\[\]@]+)(?=$|[\s\]@])/g;
16
25
  return content
17
26
  .split('\n')
18
27
  .map(line => {
19
28
  const trimmed = line.trim();
20
29
  if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('%'))
21
30
  return line;
22
- let result = line;
23
- for (const from of froms) {
24
- const to = renames.get(from);
25
- const re = new RegExp(`(^|[\\s\\[])${escapeRe(from)}(?=$|[\\s\\]@])`, 'g');
26
- result = result.replace(re, `$1${to}`);
27
- }
28
- return result;
31
+ return line.replace(tokenRe, (match, pre, token) => {
32
+ const to = renames.get(token);
33
+ return to === undefined ? match : `${pre}${to}`;
34
+ });
29
35
  })
30
36
  .join('\n');
31
37
  }