@preventive/compare 1.2.3 → 1.2.4

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/names.d.ts CHANGED
@@ -21,18 +21,19 @@ export type RenameReason = 'unparsed' | 'dynamic' | 'jsx' | 'block-function' | '
21
21
  // The diff of two JavaScript files minified on both sides with renamed names
22
22
  // set aside. The old side is given the new side's names wherever a minifier
23
23
  // renamed a variable alike throughout (a declared variable's short ASCII name,
24
- // not a script's top level, an export's or import's by its own name, or a
25
- // shorthand property's), checked to bind every name as before by this
26
- // package's scope analysis and again by oxc's minifier; formatted again where
27
- // that changes its layout alone and still binds alike; diffed as diff -U0 has
28
- // it; and the blocks checked to take `before` to the new side (thrown should
29
- // they not). `reason` says why no names were given; `reads` the properties
30
- // either text reads names through (`name`, `toString`, `stack`, `callee`,
31
- // `caller`), sorted, as code reading its names may act otherwise renamed:
32
- // none where none is renamed, and `name` only where a name renamed is a
33
- // function's or class's, the one name it reads (`function f`, `f = () => {}`);
34
- // `marks` the plain diff's blocks that differ in renamed names alone; and
35
- // `warnings` what a check that should never fail found.
24
+ // not a script's top level -- but where the file's other version is a module,
25
+ // as a bundle's chunk is once it exports, the same file loaded alike -- a name
26
+ // exported or imported as itself, or a shorthand property's), checked to bind
27
+ // every name as before by this package's scope analysis and again by oxc's
28
+ // minifier; formatted again where that changes its layout alone and still binds
29
+ // alike; diffed as diff -U0 has it; and the blocks checked to take `before` to
30
+ // the new side (thrown should they not). `reason` says why no names were given;
31
+ // `reads` the properties either text reads names through (`name`, `toString`,
32
+ // `stack`, `callee`, `caller`), sorted, as code reading its names may act
33
+ // otherwise renamed: none where none is renamed, and `name` only where a name
34
+ // renamed is a function's or class's, the one name it reads (`function f`,
35
+ // `f = () => {}`); `marks` the plain diff's blocks that differ in renamed names
36
+ // alone; and `warnings` what a check that should never fail found.
36
37
  export function renamedDiff(before: string, after: string, options?: RenameOptions & { whitespace?: Whitespace }): Promise<{
37
38
  before: string
38
39
  blocks: Pick<Block, 'a0' | 'a1' | 'b0' | 'b1'>[]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preventive/compare",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Git-compatible file tree diffs and minified JavaScript comparison",
5
5
  "type": "module",
6
6
  "main": "./compare.js",
@@ -234,7 +234,7 @@ function resolved(program, s) {
234
234
  if (s.naming.has(node)) variable.naming = true
235
235
  }
236
236
  const own = program.sourceType === 'module' || program.sourceType === 'commonjs' || globals.some(([node]) => COMMONJS.has(node.name))
237
- for (const variable of s.variables) variable.aside = variable.name.length <= RENAMED_MAX_LENGTH && MINIFIED.test(variable.name) && !variable.kept && (own || variable.scope !== s.root)
237
+ for (const variable of s.variables) variable.aside = renamable(variable) && (own || variable.scope !== s.root)
238
238
  // A shorthand property's two names are one, at one place.
239
239
  const byStart = (x, y) => x[0].start - y[0].start
240
240
  occurrences.sort(byStart)
@@ -248,6 +248,17 @@ function resolved(program, s) {
248
248
  return { scopes: s.scopes, variables: s.variables, occurrences: deduplicated, globals, names, reads: s.reads, module: program.sourceType === 'module', commonjs: program.sourceType === 'commonjs', own }
249
249
  }
250
250
 
251
+ // A short minified name, declared, and kept by no export, import or shorthand.
252
+ const renamable = (variable) => variable.name.length <= RENAMED_MAX_LENGTH && MINIFIED.test(variable.name) && !variable.kept
253
+
254
+ // A script's analysis with its top level its own, as a module's: renamable there
255
+ // too. Still read as a script, `this` and all, but no global of it set aside.
256
+ export function ownTopLevel(analysis) {
257
+ if (analysis.reason || analysis.own) return analysis
258
+ for (const variable of analysis.variables) variable.aside = renamable(variable)
259
+ return { ...analysis, own: true }
260
+ }
261
+
251
262
  export function analyze(text, extension) {
252
263
  const program = parsed(text, extension)
253
264
  if (!program) return { reason: 'unparsed' }
@@ -3,7 +3,7 @@
3
3
  // to read wrongly, and the result checked again by oxc (bindsAlike).
4
4
 
5
5
  import { getOxc } from '#oxc'
6
- import { analyze } from './analyze.js'
6
+ import { analyze, ownTopLevel } from './analyze.js'
7
7
  import { bindsAlike } from './binds.js'
8
8
  import { checkAnalysis, checkGiven, checkPairing, checkRenamed } from './check.js'
9
9
  import { misread } from './misread.js'
@@ -33,8 +33,12 @@ function givenNames(a, b, { map, weak }) {
33
33
  }
34
34
 
35
35
  function renamedNames(before, after, { extension = 'js', otherExtension = extension }) {
36
- const a = analyze(before, extension), b = analyze(after, otherExtension)
36
+ let a = analyze(before, extension), b = analyze(after, otherExtension)
37
37
  if (a.reason || b.reason) return { reason: a.reason ?? b.reason }
38
+ // A file is a module by how it is loaded, which its versions share, more than
39
+ // by its syntax: a bundle's chunk that one version exports from, the other not.
40
+ // Where its other version is a module, a script's top level is its own too.
41
+ if (a.module || b.module) [a, b] = [ownTopLevel(a), ownTopLevel(b)]
38
42
  checkAnalysis(before, a)
39
43
  checkAnalysis(after, b)
40
44
  const paired = pairing(before, after, a, b)