code-gauge 10.2.3 → 10.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/README.md +2 -2
- package/THIRD-PARTY-NOTICES.txt +12 -12
- package/dist/checkCommand.cjs.map +1 -1
- package/dist/checkCommand.js.map +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/cliConfig.cjs.map +1 -1
- package/dist/cliConfig.js.map +1 -1
- package/dist/crossFileDuplication.cjs.map +1 -1
- package/dist/crossFileDuplication.js.map +1 -1
- package/dist/crossFileNearMiss.cjs.map +1 -1
- package/dist/crossFileNearMiss.js.map +1 -1
- package/dist/duplicateSelection.cjs.map +1 -1
- package/dist/duplicateSelection.js.map +1 -1
- package/dist/duplication.cjs.map +1 -1
- package/dist/duplication.js.map +1 -1
- package/dist/exclusion.cjs.map +1 -1
- package/dist/exclusion.js.map +1 -1
- package/dist/git.cjs.map +1 -1
- package/dist/git.js.map +1 -1
- package/dist/languages.cjs.map +1 -1
- package/dist/languages.js.map +1 -1
- package/dist/metrics.cjs.map +1 -1
- package/dist/metrics.js.map +1 -1
- package/dist/nativeMetrics.cjs.map +1 -1
- package/dist/nativeMetrics.js.map +1 -1
- package/dist/scan.cjs.map +1 -1
- package/dist/scan.js.map +1 -1
- package/dist/thresholdCheck.cjs.map +1 -1
- package/dist/thresholdCheck.js.map +1 -1
- package/dist/thresholds.cjs.map +1 -1
- package/dist/thresholds.js.map +1 -1
- package/dist/wasmBinding.cjs +1 -1
- package/dist/wasmBinding.cjs.map +1 -1
- package/dist/wasmBinding.js +1 -1
- package/dist/wasmBinding.js.map +1 -1
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.js.map +1 -1
- package/native/Cargo.lock +24 -24
- package/native/Cargo.toml +12 -12
- package/native/code-gauge.wasm +0 -0
- package/package.json +14 -14
package/dist/thresholds.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thresholds.cjs","names":[],"sources":["../src/thresholds.ts"],"sourcesContent":["import type { CodeMetrics, FunctionMetrics } from './types.js';\n\n/** The severities of a violation, mildest first. */\nexport const levels = ['warning', 'error'] as const;\nexport type Level = (typeof levels)[number];\n\n/**\n * One threshold of `code-gauge check`. Its `key` is the config setting, the per-language override\n * setting, and (kebab-cased after a level prefix) the command-line options, so a new entry here is\n * all a new thresholded metric needs.\n */\nexport interface Threshold<Subject = never> {\n key: string;\n /** How the report names the measured value. */\n label: string;\n /** `Infinity` leaves the level unchecked unless the config or the command line sets a limit. */\n defaultLimits: Readonly<Record<Level, number>>;\n /** What to change in the code when the limit is exceeded. */\n hint: string;\n measure: (subject: Subject) => number;\n /**\n * The value of a function is at least that of each function nested in it, whose code it counts\n * too. Not so for Halstead difficulty and effort: a ratio can be higher for the nested part alone.\n */\n includesNestedFunctions?: true;\n}\n\n/** Limits by threshold key; `Infinity` disables a limit. */\nexport type Limits = Readonly<Record<string, number>>;\nexport type LimitsByLevel = Readonly<Record<Level, Limits>>;\n\nexport const functionThresholds: readonly Threshold<FunctionMetrics>[] = [\n {\n key: 'maxFunctionCognitiveComplexity',\n label: 'cognitive complexity',\n defaultLimits: { warning: 15, error: 30 },\n hint: 'flatten nested branching with early returns and extract nested blocks into named functions.',\n measure: (fn) => fn.cognitiveComplexity,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionCyclomaticComplexity',\n label: 'cyclomatic complexity',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function has too many independent paths; split it by decision or replace condition chains with a lookup table.',\n measure: (fn) => fn.cyclomaticComplexity,\n },\n {\n key: 'maxFunctionNcss',\n label: 'NCSS',\n defaultLimits: { warning: 30, error: 60 },\n hint: 'move each group of statements that forms one step into a named function.',\n measure: (fn) => fn.ncss,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionNestingDepth',\n label: 'nesting depth',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'replace nested conditions with guard clauses or move inner blocks into functions.',\n measure: (fn) => fn.nestingDepth,\n },\n {\n key: 'maxFunctionParameterCount',\n label: 'parameters',\n defaultLimits: { warning: 6, error: Infinity },\n hint: 'group related parameters into one object or split the function.',\n measure: (fn) => fn.parameterCount,\n },\n {\n key: 'maxFunctionHalsteadVolume',\n label: 'Halstead volume',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function holds too many operators and operands; move cohesive parts into helper functions.',\n measure: (fn) => fn.halstead.volume,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionHalsteadDifficulty',\n label: 'Halstead difficulty',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function reuses the same operands many times; split it so each part handles fewer values.',\n measure: (fn) => fn.halstead.difficulty,\n },\n {\n key: 'maxFunctionHalsteadEffort',\n label: 'Halstead effort',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function is both large and dense; split it into smaller functions with fewer values each.',\n measure: (fn) => fn.halstead.effort,\n },\n {\n key: 'maxFunctionDepDegree',\n label: 'DepDegree',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'too many values flow between the variables of the function; split it so each part works on fewer variables.',\n measure: (fn) => fn.depDegree,\n includesNestedFunctions: true,\n },\n];\n\nexport const fileThresholds: readonly Threshold<CodeMetrics>[] = [\n {\n key: 'maxFileNcss',\n label: 'file NCSS',\n defaultLimits: { warning: 400, error: 1000 },\n hint: 'split the file into modules with one responsibility each, for example by moving a class or the helpers that serve only one function into a file of their own.',\n measure: (file) => file.ncssCount,\n },\n];\n\n/**\n * A duplicated block violates when it holds at least this many duplicated lines, its code lines\n * matched in another copy: comment-only and blank lines do not count, so a copy reads the same\n * length whether or not it is commented, and neither do the lines the copies do not share, those\n * between the matched parts of an edited copy and those a near-miss copy adds or rewrites.\n */\nexport const duplicationThreshold: Threshold<{ duplicatedLineCount: number }> = {\n key: 'minDuplicateLines',\n label: 'duplicated lines',\n defaultLimits: { warning: 15, error: Infinity },\n hint: 'extract the repeated code into one shared function or module and call it from every location.',\n measure: (block) => block.duplicatedLineCount,\n};\n\nexport const thresholds: readonly Threshold[] = [...functionThresholds, ...fileThresholds, duplicationThreshold];\n\n/** The name a report gives a threshold's measured value: its key without the `max`/`min` prefix. */\nexport function metricNameOf(threshold: Threshold): string {\n const name = threshold.key.slice(3);\n return name.charAt(0).toLowerCase() + name.slice(1);\n}\n\n/** One level of the `thresholds` config section; a missing key falls back to the less specific layer. */\nexport interface LevelThresholdsConfig {\n limits: Limits;\n /** Overrides for the files of one language, keyed by language name. */\n languages: Readonly<Record<string, Limits>>;\n}\n\nexport type ThresholdsConfig = Readonly<Partial<Record<Level, LevelThresholdsConfig>>>;\n\n/**\n * The limits of each level applying to files of each language, with precedence command-line\n * options > the config's per-language overrides > the config's limits > built-in defaults.\n */\nexport function resolveLimits(\n cliLimits: LimitsByLevel,\n config: ThresholdsConfig | undefined\n): (language: string) => LimitsByLevel {\n const resolveLevel = (level: Level, language: string): Limits => {\n const levelConfig = config?.[level];\n return {\n ...Object.fromEntries(thresholds.map(({ key, defaultLimits }) => [key, defaultLimits[level]])),\n ...levelConfig?.limits,\n // Object.hasOwn: a language named like an Object.prototype member must not read an inherited value.\n ...(levelConfig && Object.hasOwn(levelConfig.languages, language) ? levelConfig.languages[language] : undefined),\n ...cliLimits[level],\n };\n };\n return (language) => ({ warning: resolveLevel('warning', language), error: resolveLevel('error', language) });\n}\n"],"mappings":"aAGA,
|
|
1
|
+
{"version":3,"file":"thresholds.cjs","names":["levels","functionThresholds","fn","fileThresholds","file","duplicationThreshold","block","thresholds","metricNameOf","name","threshold","resolveLimits","resolveLevel","levelConfig","config","level","key","defaultLimits","language","cliLimits"],"sources":["../src/thresholds.ts"],"sourcesContent":["import type { CodeMetrics, FunctionMetrics } from './types.js';\n\n/** The severities of a violation, mildest first. */\nexport const levels = ['warning', 'error'] as const;\nexport type Level = (typeof levels)[number];\n\n/**\n * One threshold of `code-gauge check`. Its `key` is the config setting, the per-language override\n * setting, and (kebab-cased after a level prefix) the command-line options, so a new entry here is\n * all a new thresholded metric needs.\n */\nexport interface Threshold<Subject = never> {\n key: string;\n /** How the report names the measured value. */\n label: string;\n /** `Infinity` leaves the level unchecked unless the config or the command line sets a limit. */\n defaultLimits: Readonly<Record<Level, number>>;\n /** What to change in the code when the limit is exceeded. */\n hint: string;\n measure: (subject: Subject) => number;\n /**\n * The value of a function is at least that of each function nested in it, whose code it counts\n * too. Not so for Halstead difficulty and effort: a ratio can be higher for the nested part alone.\n */\n includesNestedFunctions?: true;\n}\n\n/** Limits by threshold key; `Infinity` disables a limit. */\nexport type Limits = Readonly<Record<string, number>>;\nexport type LimitsByLevel = Readonly<Record<Level, Limits>>;\n\nexport const functionThresholds: readonly Threshold<FunctionMetrics>[] = [\n {\n key: 'maxFunctionCognitiveComplexity',\n label: 'cognitive complexity',\n defaultLimits: { warning: 15, error: 30 },\n hint: 'flatten nested branching with early returns and extract nested blocks into named functions.',\n measure: (fn) => fn.cognitiveComplexity,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionCyclomaticComplexity',\n label: 'cyclomatic complexity',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function has too many independent paths; split it by decision or replace condition chains with a lookup table.',\n measure: (fn) => fn.cyclomaticComplexity,\n },\n {\n key: 'maxFunctionNcss',\n label: 'NCSS',\n defaultLimits: { warning: 30, error: 60 },\n hint: 'move each group of statements that forms one step into a named function.',\n measure: (fn) => fn.ncss,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionNestingDepth',\n label: 'nesting depth',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'replace nested conditions with guard clauses or move inner blocks into functions.',\n measure: (fn) => fn.nestingDepth,\n },\n {\n key: 'maxFunctionParameterCount',\n label: 'parameters',\n defaultLimits: { warning: 6, error: Infinity },\n hint: 'group related parameters into one object or split the function.',\n measure: (fn) => fn.parameterCount,\n },\n {\n key: 'maxFunctionHalsteadVolume',\n label: 'Halstead volume',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function holds too many operators and operands; move cohesive parts into helper functions.',\n measure: (fn) => fn.halstead.volume,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionHalsteadDifficulty',\n label: 'Halstead difficulty',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function reuses the same operands many times; split it so each part handles fewer values.',\n measure: (fn) => fn.halstead.difficulty,\n },\n {\n key: 'maxFunctionHalsteadEffort',\n label: 'Halstead effort',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function is both large and dense; split it into smaller functions with fewer values each.',\n measure: (fn) => fn.halstead.effort,\n },\n {\n key: 'maxFunctionDepDegree',\n label: 'DepDegree',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'too many values flow between the variables of the function; split it so each part works on fewer variables.',\n measure: (fn) => fn.depDegree,\n includesNestedFunctions: true,\n },\n];\n\nexport const fileThresholds: readonly Threshold<CodeMetrics>[] = [\n {\n key: 'maxFileNcss',\n label: 'file NCSS',\n defaultLimits: { warning: 400, error: 1000 },\n hint: 'split the file into modules with one responsibility each, for example by moving a class or the helpers that serve only one function into a file of their own.',\n measure: (file) => file.ncssCount,\n },\n];\n\n/**\n * A duplicated block violates when it holds at least this many duplicated lines, its code lines\n * matched in another copy: comment-only and blank lines do not count, so a copy reads the same\n * length whether or not it is commented, and neither do the lines the copies do not share, those\n * between the matched parts of an edited copy and those a near-miss copy adds or rewrites.\n */\nexport const duplicationThreshold: Threshold<{ duplicatedLineCount: number }> = {\n key: 'minDuplicateLines',\n label: 'duplicated lines',\n defaultLimits: { warning: 15, error: Infinity },\n hint: 'extract the repeated code into one shared function or module and call it from every location.',\n measure: (block) => block.duplicatedLineCount,\n};\n\nexport const thresholds: readonly Threshold[] = [...functionThresholds, ...fileThresholds, duplicationThreshold];\n\n/** The name a report gives a threshold's measured value: its key without the `max`/`min` prefix. */\nexport function metricNameOf(threshold: Threshold): string {\n const name = threshold.key.slice(3);\n return name.charAt(0).toLowerCase() + name.slice(1);\n}\n\n/** One level of the `thresholds` config section; a missing key falls back to the less specific layer. */\nexport interface LevelThresholdsConfig {\n limits: Limits;\n /** Overrides for the files of one language, keyed by language name. */\n languages: Readonly<Record<string, Limits>>;\n}\n\nexport type ThresholdsConfig = Readonly<Partial<Record<Level, LevelThresholdsConfig>>>;\n\n/**\n * The limits of each level applying to files of each language, with precedence command-line\n * options > the config's per-language overrides > the config's limits > built-in defaults.\n */\nexport function resolveLimits(\n cliLimits: LimitsByLevel,\n config: ThresholdsConfig | undefined\n): (language: string) => LimitsByLevel {\n const resolveLevel = (level: Level, language: string): Limits => {\n const levelConfig = config?.[level];\n return {\n ...Object.fromEntries(thresholds.map(({ key, defaultLimits }) => [key, defaultLimits[level]])),\n ...levelConfig?.limits,\n // Object.hasOwn: a language named like an Object.prototype member must not read an inherited value.\n ...(levelConfig && Object.hasOwn(levelConfig.languages, language) ? levelConfig.languages[language] : undefined),\n ...cliLimits[level],\n };\n };\n return (language) => ({ warning: resolveLevel('warning', language), error: resolveLevel('error', language) });\n}\n"],"mappings":"aAGA,MAAaA,EAAS,CAAC,UAAW,OAAO,EA4B5BC,EAA4D,CACvE,CACE,IAAK,iCACL,MAAO,uBACP,cAAe,CAAE,QAAS,GAAI,MAAO,EAAG,EACxC,KAAM,8FACN,QAAU,GAAOC,EAAG,oBACpB,wBAAyB,EAC3B,EACA,CACE,IAAK,kCACL,MAAO,wBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,qHACN,QAAU,GAAOA,EAAG,oBACtB,EACA,CACE,IAAK,kBACL,MAAO,OACP,cAAe,CAAE,QAAS,GAAI,MAAO,EAAG,EACxC,KAAM,2EACN,QAAU,GAAOA,EAAG,KACpB,wBAAyB,EAC3B,EACA,CACE,IAAK,0BACL,MAAO,gBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,oFACN,QAAU,GAAOA,EAAG,YACtB,EACA,CACE,IAAK,4BACL,MAAO,aACP,cAAe,CAAE,QAAS,EAAG,MAAO,GAAS,EAC7C,KAAM,kEACN,QAAU,GAAOA,EAAG,cACtB,EACA,CACE,IAAK,4BACL,MAAO,kBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,iGACN,QAAU,GAAOA,EAAG,SAAS,OAC7B,wBAAyB,EAC3B,EACA,CACE,IAAK,gCACL,MAAO,sBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,gGACN,QAAU,GAAOA,EAAG,SAAS,UAC/B,EACA,CACE,IAAK,4BACL,MAAO,kBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,gGACN,QAAU,GAAOA,EAAG,SAAS,MAC/B,EACA,CACE,IAAK,uBACL,MAAO,YACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,8GACN,QAAU,GAAOA,EAAG,UACpB,wBAAyB,EAC3B,CACF,EAEaC,EAAoD,CAC/D,CACE,IAAK,cACL,MAAO,YACP,cAAe,CAAE,QAAS,IAAK,MAAO,GAAK,EAC3C,KAAM,gKACN,QAAU,GAASC,EAAK,SAC1B,CACF,EAQaC,EAAmE,CAC9E,IAAK,oBACL,MAAO,mBACP,cAAe,CAAE,QAAS,GAAI,MAAO,GAAS,EAC9C,KAAM,gGACN,QAAU,GAAUC,EAAM,mBAC5B,EAEaC,EAAmC,CAAC,GAAGN,EAAoB,GAAGE,EAAgBE,CAAoB,EAG/G,SAAgBG,EAAa,EAA8B,CACzD,IAAMC,EAAOC,EAAU,IAAI,MAAM,CAAC,EAClC,OAAOD,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAIA,EAAK,MAAM,CAAC,CACpD,CAeA,SAAgBE,EACd,EACA,EACqC,CACrC,IAAMC,GAAgB,EAAc,IAA6B,CAC/D,IAAMC,EAAcC,IAASC,GAC7B,MAAO,CACL,GAAG,OAAO,YAAYR,EAAW,KAAK,CAAE,MAAK,mBAAoB,CAACS,EAAKC,EAAcF,EAAM,CAAC,CAAC,EAC7F,GAAGF,GAAa,OAEhB,GAAIA,GAAe,OAAO,OAAOA,EAAY,UAAWK,CAAQ,EAAIL,EAAY,UAAUK,GAAY,IAAA,GACtG,GAAGC,EAAUJ,EACf,CACF,EACA,MAAQ,KAAc,CAAE,QAASH,EAAa,UAAWM,CAAQ,EAAG,MAAON,EAAa,QAASM,CAAQ,CAAE,EAC7G"}
|
package/dist/thresholds.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thresholds.js","names":[],"sources":["../src/thresholds.ts"],"sourcesContent":["import type { CodeMetrics, FunctionMetrics } from './types.js';\n\n/** The severities of a violation, mildest first. */\nexport const levels = ['warning', 'error'] as const;\nexport type Level = (typeof levels)[number];\n\n/**\n * One threshold of `code-gauge check`. Its `key` is the config setting, the per-language override\n * setting, and (kebab-cased after a level prefix) the command-line options, so a new entry here is\n * all a new thresholded metric needs.\n */\nexport interface Threshold<Subject = never> {\n key: string;\n /** How the report names the measured value. */\n label: string;\n /** `Infinity` leaves the level unchecked unless the config or the command line sets a limit. */\n defaultLimits: Readonly<Record<Level, number>>;\n /** What to change in the code when the limit is exceeded. */\n hint: string;\n measure: (subject: Subject) => number;\n /**\n * The value of a function is at least that of each function nested in it, whose code it counts\n * too. Not so for Halstead difficulty and effort: a ratio can be higher for the nested part alone.\n */\n includesNestedFunctions?: true;\n}\n\n/** Limits by threshold key; `Infinity` disables a limit. */\nexport type Limits = Readonly<Record<string, number>>;\nexport type LimitsByLevel = Readonly<Record<Level, Limits>>;\n\nexport const functionThresholds: readonly Threshold<FunctionMetrics>[] = [\n {\n key: 'maxFunctionCognitiveComplexity',\n label: 'cognitive complexity',\n defaultLimits: { warning: 15, error: 30 },\n hint: 'flatten nested branching with early returns and extract nested blocks into named functions.',\n measure: (fn) => fn.cognitiveComplexity,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionCyclomaticComplexity',\n label: 'cyclomatic complexity',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function has too many independent paths; split it by decision or replace condition chains with a lookup table.',\n measure: (fn) => fn.cyclomaticComplexity,\n },\n {\n key: 'maxFunctionNcss',\n label: 'NCSS',\n defaultLimits: { warning: 30, error: 60 },\n hint: 'move each group of statements that forms one step into a named function.',\n measure: (fn) => fn.ncss,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionNestingDepth',\n label: 'nesting depth',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'replace nested conditions with guard clauses or move inner blocks into functions.',\n measure: (fn) => fn.nestingDepth,\n },\n {\n key: 'maxFunctionParameterCount',\n label: 'parameters',\n defaultLimits: { warning: 6, error: Infinity },\n hint: 'group related parameters into one object or split the function.',\n measure: (fn) => fn.parameterCount,\n },\n {\n key: 'maxFunctionHalsteadVolume',\n label: 'Halstead volume',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function holds too many operators and operands; move cohesive parts into helper functions.',\n measure: (fn) => fn.halstead.volume,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionHalsteadDifficulty',\n label: 'Halstead difficulty',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function reuses the same operands many times; split it so each part handles fewer values.',\n measure: (fn) => fn.halstead.difficulty,\n },\n {\n key: 'maxFunctionHalsteadEffort',\n label: 'Halstead effort',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function is both large and dense; split it into smaller functions with fewer values each.',\n measure: (fn) => fn.halstead.effort,\n },\n {\n key: 'maxFunctionDepDegree',\n label: 'DepDegree',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'too many values flow between the variables of the function; split it so each part works on fewer variables.',\n measure: (fn) => fn.depDegree,\n includesNestedFunctions: true,\n },\n];\n\nexport const fileThresholds: readonly Threshold<CodeMetrics>[] = [\n {\n key: 'maxFileNcss',\n label: 'file NCSS',\n defaultLimits: { warning: 400, error: 1000 },\n hint: 'split the file into modules with one responsibility each, for example by moving a class or the helpers that serve only one function into a file of their own.',\n measure: (file) => file.ncssCount,\n },\n];\n\n/**\n * A duplicated block violates when it holds at least this many duplicated lines, its code lines\n * matched in another copy: comment-only and blank lines do not count, so a copy reads the same\n * length whether or not it is commented, and neither do the lines the copies do not share, those\n * between the matched parts of an edited copy and those a near-miss copy adds or rewrites.\n */\nexport const duplicationThreshold: Threshold<{ duplicatedLineCount: number }> = {\n key: 'minDuplicateLines',\n label: 'duplicated lines',\n defaultLimits: { warning: 15, error: Infinity },\n hint: 'extract the repeated code into one shared function or module and call it from every location.',\n measure: (block) => block.duplicatedLineCount,\n};\n\nexport const thresholds: readonly Threshold[] = [...functionThresholds, ...fileThresholds, duplicationThreshold];\n\n/** The name a report gives a threshold's measured value: its key without the `max`/`min` prefix. */\nexport function metricNameOf(threshold: Threshold): string {\n const name = threshold.key.slice(3);\n return name.charAt(0).toLowerCase() + name.slice(1);\n}\n\n/** One level of the `thresholds` config section; a missing key falls back to the less specific layer. */\nexport interface LevelThresholdsConfig {\n limits: Limits;\n /** Overrides for the files of one language, keyed by language name. */\n languages: Readonly<Record<string, Limits>>;\n}\n\nexport type ThresholdsConfig = Readonly<Partial<Record<Level, LevelThresholdsConfig>>>;\n\n/**\n * The limits of each level applying to files of each language, with precedence command-line\n * options > the config's per-language overrides > the config's limits > built-in defaults.\n */\nexport function resolveLimits(\n cliLimits: LimitsByLevel,\n config: ThresholdsConfig | undefined\n): (language: string) => LimitsByLevel {\n const resolveLevel = (level: Level, language: string): Limits => {\n const levelConfig = config?.[level];\n return {\n ...Object.fromEntries(thresholds.map(({ key, defaultLimits }) => [key, defaultLimits[level]])),\n ...levelConfig?.limits,\n // Object.hasOwn: a language named like an Object.prototype member must not read an inherited value.\n ...(levelConfig && Object.hasOwn(levelConfig.languages, language) ? levelConfig.languages[language] : undefined),\n ...cliLimits[level],\n };\n };\n return (language) => ({ warning: resolveLevel('warning', language), error: resolveLevel('error', language) });\n}\n"],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"thresholds.js","names":["levels","functionThresholds","fn","fileThresholds","file","duplicationThreshold","block","thresholds","metricNameOf","name","threshold","resolveLimits","resolveLevel","levelConfig","config","level","key","defaultLimits","language","cliLimits"],"sources":["../src/thresholds.ts"],"sourcesContent":["import type { CodeMetrics, FunctionMetrics } from './types.js';\n\n/** The severities of a violation, mildest first. */\nexport const levels = ['warning', 'error'] as const;\nexport type Level = (typeof levels)[number];\n\n/**\n * One threshold of `code-gauge check`. Its `key` is the config setting, the per-language override\n * setting, and (kebab-cased after a level prefix) the command-line options, so a new entry here is\n * all a new thresholded metric needs.\n */\nexport interface Threshold<Subject = never> {\n key: string;\n /** How the report names the measured value. */\n label: string;\n /** `Infinity` leaves the level unchecked unless the config or the command line sets a limit. */\n defaultLimits: Readonly<Record<Level, number>>;\n /** What to change in the code when the limit is exceeded. */\n hint: string;\n measure: (subject: Subject) => number;\n /**\n * The value of a function is at least that of each function nested in it, whose code it counts\n * too. Not so for Halstead difficulty and effort: a ratio can be higher for the nested part alone.\n */\n includesNestedFunctions?: true;\n}\n\n/** Limits by threshold key; `Infinity` disables a limit. */\nexport type Limits = Readonly<Record<string, number>>;\nexport type LimitsByLevel = Readonly<Record<Level, Limits>>;\n\nexport const functionThresholds: readonly Threshold<FunctionMetrics>[] = [\n {\n key: 'maxFunctionCognitiveComplexity',\n label: 'cognitive complexity',\n defaultLimits: { warning: 15, error: 30 },\n hint: 'flatten nested branching with early returns and extract nested blocks into named functions.',\n measure: (fn) => fn.cognitiveComplexity,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionCyclomaticComplexity',\n label: 'cyclomatic complexity',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function has too many independent paths; split it by decision or replace condition chains with a lookup table.',\n measure: (fn) => fn.cyclomaticComplexity,\n },\n {\n key: 'maxFunctionNcss',\n label: 'NCSS',\n defaultLimits: { warning: 30, error: 60 },\n hint: 'move each group of statements that forms one step into a named function.',\n measure: (fn) => fn.ncss,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionNestingDepth',\n label: 'nesting depth',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'replace nested conditions with guard clauses or move inner blocks into functions.',\n measure: (fn) => fn.nestingDepth,\n },\n {\n key: 'maxFunctionParameterCount',\n label: 'parameters',\n defaultLimits: { warning: 6, error: Infinity },\n hint: 'group related parameters into one object or split the function.',\n measure: (fn) => fn.parameterCount,\n },\n {\n key: 'maxFunctionHalsteadVolume',\n label: 'Halstead volume',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function holds too many operators and operands; move cohesive parts into helper functions.',\n measure: (fn) => fn.halstead.volume,\n includesNestedFunctions: true,\n },\n {\n key: 'maxFunctionHalsteadDifficulty',\n label: 'Halstead difficulty',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function reuses the same operands many times; split it so each part handles fewer values.',\n measure: (fn) => fn.halstead.difficulty,\n },\n {\n key: 'maxFunctionHalsteadEffort',\n label: 'Halstead effort',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'the function is both large and dense; split it into smaller functions with fewer values each.',\n measure: (fn) => fn.halstead.effort,\n },\n {\n key: 'maxFunctionDepDegree',\n label: 'DepDegree',\n defaultLimits: { warning: Infinity, error: Infinity },\n hint: 'too many values flow between the variables of the function; split it so each part works on fewer variables.',\n measure: (fn) => fn.depDegree,\n includesNestedFunctions: true,\n },\n];\n\nexport const fileThresholds: readonly Threshold<CodeMetrics>[] = [\n {\n key: 'maxFileNcss',\n label: 'file NCSS',\n defaultLimits: { warning: 400, error: 1000 },\n hint: 'split the file into modules with one responsibility each, for example by moving a class or the helpers that serve only one function into a file of their own.',\n measure: (file) => file.ncssCount,\n },\n];\n\n/**\n * A duplicated block violates when it holds at least this many duplicated lines, its code lines\n * matched in another copy: comment-only and blank lines do not count, so a copy reads the same\n * length whether or not it is commented, and neither do the lines the copies do not share, those\n * between the matched parts of an edited copy and those a near-miss copy adds or rewrites.\n */\nexport const duplicationThreshold: Threshold<{ duplicatedLineCount: number }> = {\n key: 'minDuplicateLines',\n label: 'duplicated lines',\n defaultLimits: { warning: 15, error: Infinity },\n hint: 'extract the repeated code into one shared function or module and call it from every location.',\n measure: (block) => block.duplicatedLineCount,\n};\n\nexport const thresholds: readonly Threshold[] = [...functionThresholds, ...fileThresholds, duplicationThreshold];\n\n/** The name a report gives a threshold's measured value: its key without the `max`/`min` prefix. */\nexport function metricNameOf(threshold: Threshold): string {\n const name = threshold.key.slice(3);\n return name.charAt(0).toLowerCase() + name.slice(1);\n}\n\n/** One level of the `thresholds` config section; a missing key falls back to the less specific layer. */\nexport interface LevelThresholdsConfig {\n limits: Limits;\n /** Overrides for the files of one language, keyed by language name. */\n languages: Readonly<Record<string, Limits>>;\n}\n\nexport type ThresholdsConfig = Readonly<Partial<Record<Level, LevelThresholdsConfig>>>;\n\n/**\n * The limits of each level applying to files of each language, with precedence command-line\n * options > the config's per-language overrides > the config's limits > built-in defaults.\n */\nexport function resolveLimits(\n cliLimits: LimitsByLevel,\n config: ThresholdsConfig | undefined\n): (language: string) => LimitsByLevel {\n const resolveLevel = (level: Level, language: string): Limits => {\n const levelConfig = config?.[level];\n return {\n ...Object.fromEntries(thresholds.map(({ key, defaultLimits }) => [key, defaultLimits[level]])),\n ...levelConfig?.limits,\n // Object.hasOwn: a language named like an Object.prototype member must not read an inherited value.\n ...(levelConfig && Object.hasOwn(levelConfig.languages, language) ? levelConfig.languages[language] : undefined),\n ...cliLimits[level],\n };\n };\n return (language) => ({ warning: resolveLevel('warning', language), error: resolveLevel('error', language) });\n}\n"],"mappings":"AAGA,MAAaA,EAAS,CAAC,UAAW,OAAO,EA4B5BC,EAA4D,CACvE,CACE,IAAK,iCACL,MAAO,uBACP,cAAe,CAAE,QAAS,GAAI,MAAO,EAAG,EACxC,KAAM,8FACN,QAAU,GAAOC,EAAG,oBACpB,wBAAyB,EAC3B,EACA,CACE,IAAK,kCACL,MAAO,wBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,qHACN,QAAU,GAAOA,EAAG,oBACtB,EACA,CACE,IAAK,kBACL,MAAO,OACP,cAAe,CAAE,QAAS,GAAI,MAAO,EAAG,EACxC,KAAM,2EACN,QAAU,GAAOA,EAAG,KACpB,wBAAyB,EAC3B,EACA,CACE,IAAK,0BACL,MAAO,gBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,oFACN,QAAU,GAAOA,EAAG,YACtB,EACA,CACE,IAAK,4BACL,MAAO,aACP,cAAe,CAAE,QAAS,EAAG,MAAO,GAAS,EAC7C,KAAM,kEACN,QAAU,GAAOA,EAAG,cACtB,EACA,CACE,IAAK,4BACL,MAAO,kBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,iGACN,QAAU,GAAOA,EAAG,SAAS,OAC7B,wBAAyB,EAC3B,EACA,CACE,IAAK,gCACL,MAAO,sBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,gGACN,QAAU,GAAOA,EAAG,SAAS,UAC/B,EACA,CACE,IAAK,4BACL,MAAO,kBACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,gGACN,QAAU,GAAOA,EAAG,SAAS,MAC/B,EACA,CACE,IAAK,uBACL,MAAO,YACP,cAAe,CAAE,QAAS,IAAU,MAAO,GAAS,EACpD,KAAM,8GACN,QAAU,GAAOA,EAAG,UACpB,wBAAyB,EAC3B,CACF,EAEaC,EAAoD,CAC/D,CACE,IAAK,cACL,MAAO,YACP,cAAe,CAAE,QAAS,IAAK,MAAO,GAAK,EAC3C,KAAM,gKACN,QAAU,GAASC,EAAK,SAC1B,CACF,EAQaC,EAAmE,CAC9E,IAAK,oBACL,MAAO,mBACP,cAAe,CAAE,QAAS,GAAI,MAAO,GAAS,EAC9C,KAAM,gGACN,QAAU,GAAUC,EAAM,mBAC5B,EAEaC,EAAmC,CAAC,GAAGN,EAAoB,GAAGE,EAAgBE,CAAoB,EAG/G,SAAgBG,EAAa,EAA8B,CACzD,IAAMC,EAAOC,EAAU,IAAI,MAAM,CAAC,EAClC,OAAOD,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAIA,EAAK,MAAM,CAAC,CACpD,CAeA,SAAgBE,EACd,EACA,EACqC,CACrC,IAAMC,GAAgB,EAAc,IAA6B,CAC/D,IAAMC,EAAcC,IAASC,GAC7B,MAAO,CACL,GAAG,OAAO,YAAYR,EAAW,KAAK,CAAE,MAAK,mBAAoB,CAACS,EAAKC,EAAcF,EAAM,CAAC,CAAC,EAC7F,GAAGF,GAAa,OAEhB,GAAIA,GAAe,OAAO,OAAOA,EAAY,UAAWK,CAAQ,EAAIL,EAAY,UAAUK,GAAY,IAAA,GACtG,GAAGC,EAAUJ,EACf,CACF,EACA,MAAQ,KAAc,CAAE,QAASH,EAAa,UAAWM,CAAQ,EAAG,MAAON,EAAa,QAASM,CAAQ,CAAE,EAC7G"}
|
package/dist/wasmBinding.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const e=require("./nativeMetrics.cjs"),t=new TextEncoder,n=new TextDecoder;function r(e){let t,r,s=a=>{if(!t){if(r)throw r;try{t=i(e)}catch(e){throw r=e,e}}let{exports:o,stderr:s}=t;s.length=0;let c;try{c=a(o)}catch(e){throw t=void 0,Error(`The code-gauge WebAssembly module crashed: ${s.join(``).trim()||String(e)}`,{cause:e})}let l=n.decode(new Uint8Array(o.memory.buffer,o.result_ptr(),o.result_len()));if(c!==0)throw Error(l);return l},c=(e,t,n,r,i,c,l)=>s(s=>s.measure_code(...a(s,e),...a(s,t),Number(n),o(r),o(i),o(c),Number(l)));return{measureCodeNative:c,measureCodeNativeAsync:async(...e)=>c(...e),collectCrossFileDataNative:(e,t,n)=>s(r=>r.collect_cross_file_data(...a(r,e),...a(r,t),o(n))),collectFunctionTokenSequencesNative:(e,t)=>s(n=>n.collect_function_token_sequences(...a(n,e),...a(n,t)))}}function i(t){let n=[],r,i=new WebAssembly.Instance(t,{wasi_snapshot_preview1:c(()=>r,n)}).exports;r=i.memory;let a=i.payload_version();if(a!==12)throw new e.NativeAddonError(`The code-gauge WebAssembly module has payload version ${a}, but 12 is expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with \`bun run build-wasm\``);return{exports:i,stderr:n}}function a(e,n){let r=t.encode(n),i=e.alloc(r.length);return new Uint8Array(e.memory.buffer,i,r.length).set(r),[i,r.length]}function o(e){return e??-1}const s=65536;function c(e,t){let r=()=>new DataView(e().buffer)
|
|
1
|
+
"use strict";const e=require("./nativeMetrics.cjs"),t=new TextEncoder,n=new TextDecoder;function r(e){let t,r,s=a=>{if(!t){if(r)throw r;try{t=i(e)}catch(e){throw r=e,e}}let{exports:o,stderr:s}=t;s.length=0;let c;try{c=a(o)}catch(e){throw t=void 0,Error(`The code-gauge WebAssembly module crashed: ${s.join(``).trim()||String(e)}`,{cause:e})}let l=n.decode(new Uint8Array(o.memory.buffer,o.result_ptr(),o.result_len()));if(c!==0)throw Error(l);return l},c=(e,t,n,r,i,c,l)=>s(s=>s.measure_code(...a(s,e),...a(s,t),Number(n),o(r),o(i),o(c),Number(l)));return{measureCodeNative:c,measureCodeNativeAsync:async(...e)=>c(...e),collectCrossFileDataNative:(e,t,n)=>s(r=>r.collect_cross_file_data(...a(r,e),...a(r,t),o(n))),collectFunctionTokenSequencesNative:(e,t)=>s(n=>n.collect_function_token_sequences(...a(n,e),...a(n,t)))}}function i(t){let n=[],r,i=new WebAssembly.Instance(t,{wasi_snapshot_preview1:c(()=>r,n)}).exports;r=i.memory;let a=i.payload_version();if(a!==12)throw new e.NativeAddonError(`The code-gauge WebAssembly module has payload version ${a}, but 12 is expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with \`bun run build-wasm\``);return{exports:i,stderr:n}}function a(e,n){let r=t.encode(n),i=e.alloc(r.length);return new Uint8Array(e.memory.buffer,i,r.length).set(r),[i,r.length]}function o(e){return e??-1}const s=65536;function c(e,t){let r=()=>new DataView(e().buffer);return{environ_get:()=>0,environ_sizes_get:(e,t)=>(r().setUint32(e,0,!0),r().setUint32(t,0,!0),0),clock_time_get:(e,t,n)=>(r().setBigUint64(n,BigInt(Date.now())*1000000n,!0),0),random_get:(t,n)=>{for(let r=0;r<n;r+=s)crypto.getRandomValues(new Uint8Array(e().buffer,t+r,Math.min(s,n-r)));return 0},fd_write:(i,a,o,s)=>{let c=r(),l=0;for(let r=0;r<o;r++){let o=c.getUint32(a+r*8,!0),s=c.getUint32(a+r*8+4,!0);i===2&&t.push(n.decode(new Uint8Array(e().buffer,o,s))),l+=s}return c.setUint32(s,l,!0),0},fd_close:l,fd_fdstat_get:l,fd_fdstat_set_flags:l,fd_read:l,fd_seek:l,proc_exit:e=>{throw Error(`The code-gauge WebAssembly module exited with code ${e}`)}}}function l(){return 8}exports.createWasmBinding=r;
|
|
2
2
|
//# sourceMappingURL=wasmBinding.cjs.map
|
package/dist/wasmBinding.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasmBinding.cjs","names":["NativeAddonError"],"sources":["../src/wasmBinding.ts"],"sourcesContent":["import { expectedPayloadVersion, NativeAddonError, type NativeBinding } from './nativeMetrics.js';\n\n/** The C ABI exported by native/src/wasm.rs. */\ninterface WasmExports {\n memory: WebAssembly.Memory;\n payload_version(): number;\n alloc(length: number): number;\n result_ptr(): number;\n result_len(): number;\n measure_code(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n includeSyntaxTree: number,\n minTokens: number,\n maxGapTokens: number,\n minSimilarityPercent: number,\n includeCrossFileData: number\n ): number;\n collect_cross_file_data(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n minTokens: number\n ): number;\n collect_function_token_sequences(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number\n ): number;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Wraps the WebAssembly build of the native addon (native/src/wasm.rs) as a NativeBinding. The\n * module is instantiated synchronously on first use and again after a trap (a panic or stack\n * overflow), because a trap leaves the instance's memory and stack pointer in an undefined state.\n * An instantiation failure (e.g., a payload version mismatch) is memoized like the N-API loader's,\n * since instantiating the same module again would fail again.\n */\nexport function createWasmBinding(module: WebAssembly.Module): NativeBinding {\n let instance: { exports: WasmExports; stderr: string[] } | undefined;\n let instantiationFailure: unknown;\n\n const call = (invoke: (exports: WasmExports) => number): string => {\n if (!instance) {\n if (instantiationFailure) {\n throw instantiationFailure;\n }\n try {\n instance = instantiate(module);\n } catch (error) {\n instantiationFailure = error;\n throw error;\n }\n }\n const { exports, stderr } = instance;\n stderr.length = 0;\n let status: number;\n try {\n status = invoke(exports);\n } catch (error) {\n instance = undefined;\n throw new Error(`The code-gauge WebAssembly module crashed: ${stderr.join('').trim() || String(error)}`, {\n cause: error,\n });\n }\n const result = decoder.decode(new Uint8Array(exports.memory.buffer, exports.result_ptr(), exports.result_len()));\n if (status !== 0) {\n throw new Error(result);\n }\n return result;\n };\n\n const measureCodeNative: NativeBinding['measureCodeNative'] = (\n code,\n language,\n includeSyntaxTree,\n minTokens,\n maxGapTokens,\n minSimilarityPercent,\n includeCrossFileData\n ) =>\n call((exports) =>\n exports.measure_code(\n ...passString(exports, code),\n ...passString(exports, language),\n Number(includeSyntaxTree),\n toOptionalU32(minTokens),\n toOptionalU32(maxGapTokens),\n toOptionalU32(minSimilarityPercent),\n Number(includeCrossFileData)\n )\n );\n\n return {\n measureCodeNative,\n // The WebAssembly build has no threads, so the asynchronous form measures in place.\n measureCodeNativeAsync: async (...args) => measureCodeNative(...args),\n collectCrossFileDataNative: (code, language, minTokens) =>\n call((exports) =>\n exports.collect_cross_file_data(\n ...passString(exports, code),\n ...passString(exports, language),\n toOptionalU32(minTokens)\n )\n ),\n collectFunctionTokenSequencesNative: (code, language) =>\n call((exports) =>\n exports.collect_function_token_sequences(...passString(exports, code), ...passString(exports, language))\n ),\n };\n}\n\nfunction instantiate(module: WebAssembly.Module): { exports: WasmExports; stderr: string[] } {\n const stderr: string[] = [];\n let memory: WebAssembly.Memory | undefined;\n const instance = new WebAssembly.Instance(module, {\n wasi_snapshot_preview1: createWasiImports(() => memory as WebAssembly.Memory, stderr),\n });\n const exports = instance.exports as unknown as WasmExports;\n memory = exports.memory;\n const version = exports.payload_version();\n if (version !== expectedPayloadVersion) {\n throw new NativeAddonError(\n `The code-gauge WebAssembly module has payload version ${version}, but ${expectedPayloadVersion} is ` +\n 'expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with `bun run build-wasm`'\n );\n }\n return { exports, stderr };\n}\n\n/** Copies a string into a buffer whose ownership passes to the called export. */\nfunction passString(exports: WasmExports, text: string): [number, number] {\n // TextEncoder replaces lone surrogates with U+FFFD, like toWellFormed() does for the N-API addon.\n const bytes = encoder.encode(text);\n const pointer = exports.alloc(bytes.length);\n new Uint8Array(exports.memory.buffer, pointer, bytes.length).set(bytes);\n return [pointer, bytes.length];\n}\n\n/** native/src/wasm.rs reads a negative value as an absent setting. */\nfunction toOptionalU32(value: number | undefined): number {\n return value ?? -1;\n}\n\nconst WASI_ERRNO_SUCCESS = 0;\nconst WASI_ERRNO_BADF = 8;\n// crypto.getRandomValues() rejects requests larger than this.\nconst MAX_RANDOM_BYTES = 65_536;\n\n/**\n * The WASI preview 1 functions the module imports. The metrics code performs no I/O, so file\n * descriptors are unavailable except for writes, whose stderr output (e.g., a panic message) is\n * kept for the error raised when the module traps.\n */\nfunction createWasiImports(\n getMemory: () => WebAssembly.Memory,\n stderr: string[]\n): Record<string, (...args: never[]) => number> {\n const view = (): DataView => new DataView(getMemory().buffer);\n const unavailable = (): number => WASI_ERRNO_BADF;\n return {\n environ_get: () => WASI_ERRNO_SUCCESS,\n environ_sizes_get: (countPointer: number, sizePointer: number) => {\n view().setUint32(countPointer, 0, true);\n view().setUint32(sizePointer, 0, true);\n return WASI_ERRNO_SUCCESS;\n },\n clock_time_get: (_clockId: number, _precision: bigint, timePointer: number) => {\n view().setBigUint64(timePointer, BigInt(Date.now()) * 1_000_000n, true);\n return WASI_ERRNO_SUCCESS;\n },\n random_get: (pointer: number, length: number) => {\n for (let offset = 0; offset < length; offset += MAX_RANDOM_BYTES) {\n crypto.getRandomValues(\n new Uint8Array(getMemory().buffer, pointer + offset, Math.min(MAX_RANDOM_BYTES, length - offset))\n );\n }\n return WASI_ERRNO_SUCCESS;\n },\n fd_write: (fd: number, iovsPointer: number, iovsLength: number, writtenPointer: number) => {\n const memoryView = view();\n let written = 0;\n for (let index = 0; index < iovsLength; index++) {\n const pointer = memoryView.getUint32(iovsPointer + index * 8, true);\n const length = memoryView.getUint32(iovsPointer + index * 8 + 4, true);\n if (fd === 2) {\n stderr.push(decoder.decode(new Uint8Array(getMemory().buffer, pointer, length)));\n }\n written += length;\n }\n memoryView.setUint32(writtenPointer, written, true);\n return WASI_ERRNO_SUCCESS;\n },\n fd_close: unavailable,\n fd_fdstat_get: unavailable,\n fd_fdstat_set_flags: unavailable,\n fd_read: unavailable,\n fd_seek: unavailable,\n proc_exit: (code: number) => {\n throw new Error(`The code-gauge WebAssembly module exited with code ${code}`);\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wasmBinding.cjs","names":["NativeAddonError","require_nativeMetrics","encoder","decoder","createWasmBinding","instance","instantiationFailure","call","instantiate","module","error","status","invoke","exports","stderr","result","measureCodeNative","passString","code","language","includeSyntaxTree","toOptionalU32","minTokens","maxGapTokens","minSimilarityPercent","includeCrossFileData","args","memory","createWasiImports","version","bytes","text","pointer","value","MAX_RANDOM_BYTES","view","getMemory","countPointer","sizePointer","timePointer","offset","length","memoryView","written","index","iovsLength","iovsPointer","fd","writtenPointer","unavailable"],"sources":["../src/wasmBinding.ts"],"sourcesContent":["import { expectedPayloadVersion, NativeAddonError, type NativeBinding } from './nativeMetrics.js';\n\n/** The C ABI exported by native/src/wasm.rs. */\ninterface WasmExports {\n memory: WebAssembly.Memory;\n payload_version(): number;\n alloc(length: number): number;\n result_ptr(): number;\n result_len(): number;\n measure_code(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n includeSyntaxTree: number,\n minTokens: number,\n maxGapTokens: number,\n minSimilarityPercent: number,\n includeCrossFileData: number\n ): number;\n collect_cross_file_data(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n minTokens: number\n ): number;\n collect_function_token_sequences(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number\n ): number;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Wraps the WebAssembly build of the native addon (native/src/wasm.rs) as a NativeBinding. The\n * module is instantiated synchronously on first use and again after a trap (a panic or stack\n * overflow), because a trap leaves the instance's memory and stack pointer in an undefined state.\n * An instantiation failure (e.g., a payload version mismatch) is memoized like the N-API loader's,\n * since instantiating the same module again would fail again.\n */\nexport function createWasmBinding(module: WebAssembly.Module): NativeBinding {\n let instance: { exports: WasmExports; stderr: string[] } | undefined;\n let instantiationFailure: unknown;\n\n const call = (invoke: (exports: WasmExports) => number): string => {\n if (!instance) {\n if (instantiationFailure) {\n throw instantiationFailure;\n }\n try {\n instance = instantiate(module);\n } catch (error) {\n instantiationFailure = error;\n throw error;\n }\n }\n const { exports, stderr } = instance;\n stderr.length = 0;\n let status: number;\n try {\n status = invoke(exports);\n } catch (error) {\n instance = undefined;\n throw new Error(`The code-gauge WebAssembly module crashed: ${stderr.join('').trim() || String(error)}`, {\n cause: error,\n });\n }\n const result = decoder.decode(new Uint8Array(exports.memory.buffer, exports.result_ptr(), exports.result_len()));\n if (status !== 0) {\n throw new Error(result);\n }\n return result;\n };\n\n const measureCodeNative: NativeBinding['measureCodeNative'] = (\n code,\n language,\n includeSyntaxTree,\n minTokens,\n maxGapTokens,\n minSimilarityPercent,\n includeCrossFileData\n ) =>\n call((exports) =>\n exports.measure_code(\n ...passString(exports, code),\n ...passString(exports, language),\n Number(includeSyntaxTree),\n toOptionalU32(minTokens),\n toOptionalU32(maxGapTokens),\n toOptionalU32(minSimilarityPercent),\n Number(includeCrossFileData)\n )\n );\n\n return {\n measureCodeNative,\n // The WebAssembly build has no threads, so the asynchronous form measures in place.\n measureCodeNativeAsync: async (...args) => measureCodeNative(...args),\n collectCrossFileDataNative: (code, language, minTokens) =>\n call((exports) =>\n exports.collect_cross_file_data(\n ...passString(exports, code),\n ...passString(exports, language),\n toOptionalU32(minTokens)\n )\n ),\n collectFunctionTokenSequencesNative: (code, language) =>\n call((exports) =>\n exports.collect_function_token_sequences(...passString(exports, code), ...passString(exports, language))\n ),\n };\n}\n\nfunction instantiate(module: WebAssembly.Module): { exports: WasmExports; stderr: string[] } {\n const stderr: string[] = [];\n let memory: WebAssembly.Memory | undefined;\n const instance = new WebAssembly.Instance(module, {\n wasi_snapshot_preview1: createWasiImports(() => memory as WebAssembly.Memory, stderr),\n });\n const exports = instance.exports as unknown as WasmExports;\n memory = exports.memory;\n const version = exports.payload_version();\n if (version !== expectedPayloadVersion) {\n throw new NativeAddonError(\n `The code-gauge WebAssembly module has payload version ${version}, but ${expectedPayloadVersion} is ` +\n 'expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with `bun run build-wasm`'\n );\n }\n return { exports, stderr };\n}\n\n/** Copies a string into a buffer whose ownership passes to the called export. */\nfunction passString(exports: WasmExports, text: string): [number, number] {\n // TextEncoder replaces lone surrogates with U+FFFD, like toWellFormed() does for the N-API addon.\n const bytes = encoder.encode(text);\n const pointer = exports.alloc(bytes.length);\n new Uint8Array(exports.memory.buffer, pointer, bytes.length).set(bytes);\n return [pointer, bytes.length];\n}\n\n/** native/src/wasm.rs reads a negative value as an absent setting. */\nfunction toOptionalU32(value: number | undefined): number {\n return value ?? -1;\n}\n\nconst WASI_ERRNO_SUCCESS = 0;\nconst WASI_ERRNO_BADF = 8;\n// crypto.getRandomValues() rejects requests larger than this.\nconst MAX_RANDOM_BYTES = 65_536;\n\n/**\n * The WASI preview 1 functions the module imports. The metrics code performs no I/O, so file\n * descriptors are unavailable except for writes, whose stderr output (e.g., a panic message) is\n * kept for the error raised when the module traps.\n */\nfunction createWasiImports(\n getMemory: () => WebAssembly.Memory,\n stderr: string[]\n): Record<string, (...args: never[]) => number> {\n const view = (): DataView => new DataView(getMemory().buffer);\n return {\n environ_get: () => WASI_ERRNO_SUCCESS,\n environ_sizes_get: (countPointer: number, sizePointer: number) => {\n view().setUint32(countPointer, 0, true);\n view().setUint32(sizePointer, 0, true);\n return WASI_ERRNO_SUCCESS;\n },\n clock_time_get: (_clockId: number, _precision: bigint, timePointer: number) => {\n view().setBigUint64(timePointer, BigInt(Date.now()) * 1_000_000n, true);\n return WASI_ERRNO_SUCCESS;\n },\n random_get: (pointer: number, length: number) => {\n for (let offset = 0; offset < length; offset += MAX_RANDOM_BYTES) {\n crypto.getRandomValues(\n new Uint8Array(getMemory().buffer, pointer + offset, Math.min(MAX_RANDOM_BYTES, length - offset))\n );\n }\n return WASI_ERRNO_SUCCESS;\n },\n fd_write: (fd: number, iovsPointer: number, iovsLength: number, writtenPointer: number) => {\n const memoryView = view();\n let written = 0;\n for (let index = 0; index < iovsLength; index++) {\n const pointer = memoryView.getUint32(iovsPointer + index * 8, true);\n const length = memoryView.getUint32(iovsPointer + index * 8 + 4, true);\n if (fd === 2) {\n stderr.push(decoder.decode(new Uint8Array(getMemory().buffer, pointer, length)));\n }\n written += length;\n }\n memoryView.setUint32(writtenPointer, written, true);\n return WASI_ERRNO_SUCCESS;\n },\n fd_close: unavailable,\n fd_fdstat_get: unavailable,\n fd_fdstat_set_flags: unavailable,\n fd_read: unavailable,\n fd_seek: unavailable,\n proc_exit: (code: number) => {\n throw new Error(`The code-gauge WebAssembly module exited with code ${code}`);\n },\n };\n}\n\nfunction unavailable(): number {\n return WASI_ERRNO_BADF;\n}\n"],"mappings":"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"}
|
package/dist/wasmBinding.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{NativeAddonError as e}from"./nativeMetrics.js";const t=new TextEncoder,n=new TextDecoder;function r(e){let t,r,s=a=>{if(!t){if(r)throw r;try{t=i(e)}catch(e){throw r=e,e}}let{exports:o,stderr:s}=t;s.length=0;let c;try{c=a(o)}catch(e){throw t=void 0,Error(`The code-gauge WebAssembly module crashed: ${s.join(``).trim()||String(e)}`,{cause:e})}let l=n.decode(new Uint8Array(o.memory.buffer,o.result_ptr(),o.result_len()));if(c!==0)throw Error(l);return l},c=(e,t,n,r,i,c,l)=>s(s=>s.measure_code(...a(s,e),...a(s,t),Number(n),o(r),o(i),o(c),Number(l)));return{measureCodeNative:c,measureCodeNativeAsync:async(...e)=>c(...e),collectCrossFileDataNative:(e,t,n)=>s(r=>r.collect_cross_file_data(...a(r,e),...a(r,t),o(n))),collectFunctionTokenSequencesNative:(e,t)=>s(n=>n.collect_function_token_sequences(...a(n,e),...a(n,t)))}}function i(t){let n=[],r,i=new WebAssembly.Instance(t,{wasi_snapshot_preview1:c(()=>r,n)}).exports;r=i.memory;let a=i.payload_version();if(a!==12)throw new e(`The code-gauge WebAssembly module has payload version ${a}, but 12 is expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with \`bun run build-wasm\``);return{exports:i,stderr:n}}function a(e,n){let r=t.encode(n),i=e.alloc(r.length);return new Uint8Array(e.memory.buffer,i,r.length).set(r),[i,r.length]}function o(e){return e??-1}const s=65536;function c(e,t){let r=()=>new DataView(e().buffer)
|
|
1
|
+
import{NativeAddonError as e}from"./nativeMetrics.js";const t=new TextEncoder,n=new TextDecoder;function r(e){let t,r,s=a=>{if(!t){if(r)throw r;try{t=i(e)}catch(e){throw r=e,e}}let{exports:o,stderr:s}=t;s.length=0;let c;try{c=a(o)}catch(e){throw t=void 0,Error(`The code-gauge WebAssembly module crashed: ${s.join(``).trim()||String(e)}`,{cause:e})}let l=n.decode(new Uint8Array(o.memory.buffer,o.result_ptr(),o.result_len()));if(c!==0)throw Error(l);return l},c=(e,t,n,r,i,c,l)=>s(s=>s.measure_code(...a(s,e),...a(s,t),Number(n),o(r),o(i),o(c),Number(l)));return{measureCodeNative:c,measureCodeNativeAsync:async(...e)=>c(...e),collectCrossFileDataNative:(e,t,n)=>s(r=>r.collect_cross_file_data(...a(r,e),...a(r,t),o(n))),collectFunctionTokenSequencesNative:(e,t)=>s(n=>n.collect_function_token_sequences(...a(n,e),...a(n,t)))}}function i(t){let n=[],r,i=new WebAssembly.Instance(t,{wasi_snapshot_preview1:c(()=>r,n)}).exports;r=i.memory;let a=i.payload_version();if(a!==12)throw new e(`The code-gauge WebAssembly module has payload version ${a}, but 12 is expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with \`bun run build-wasm\``);return{exports:i,stderr:n}}function a(e,n){let r=t.encode(n),i=e.alloc(r.length);return new Uint8Array(e.memory.buffer,i,r.length).set(r),[i,r.length]}function o(e){return e??-1}const s=65536;function c(e,t){let r=()=>new DataView(e().buffer);return{environ_get:()=>0,environ_sizes_get:(e,t)=>(r().setUint32(e,0,!0),r().setUint32(t,0,!0),0),clock_time_get:(e,t,n)=>(r().setBigUint64(n,BigInt(Date.now())*1000000n,!0),0),random_get:(t,n)=>{for(let r=0;r<n;r+=s)crypto.getRandomValues(new Uint8Array(e().buffer,t+r,Math.min(s,n-r)));return 0},fd_write:(i,a,o,s)=>{let c=r(),l=0;for(let r=0;r<o;r++){let o=c.getUint32(a+r*8,!0),s=c.getUint32(a+r*8+4,!0);i===2&&t.push(n.decode(new Uint8Array(e().buffer,o,s))),l+=s}return c.setUint32(s,l,!0),0},fd_close:l,fd_fdstat_get:l,fd_fdstat_set_flags:l,fd_read:l,fd_seek:l,proc_exit:e=>{throw Error(`The code-gauge WebAssembly module exited with code ${e}`)}}}function l(){return 8}export{r as createWasmBinding};
|
|
2
2
|
//# sourceMappingURL=wasmBinding.js.map
|
package/dist/wasmBinding.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasmBinding.js","names":[],"sources":["../src/wasmBinding.ts"],"sourcesContent":["import { expectedPayloadVersion, NativeAddonError, type NativeBinding } from './nativeMetrics.js';\n\n/** The C ABI exported by native/src/wasm.rs. */\ninterface WasmExports {\n memory: WebAssembly.Memory;\n payload_version(): number;\n alloc(length: number): number;\n result_ptr(): number;\n result_len(): number;\n measure_code(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n includeSyntaxTree: number,\n minTokens: number,\n maxGapTokens: number,\n minSimilarityPercent: number,\n includeCrossFileData: number\n ): number;\n collect_cross_file_data(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n minTokens: number\n ): number;\n collect_function_token_sequences(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number\n ): number;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Wraps the WebAssembly build of the native addon (native/src/wasm.rs) as a NativeBinding. The\n * module is instantiated synchronously on first use and again after a trap (a panic or stack\n * overflow), because a trap leaves the instance's memory and stack pointer in an undefined state.\n * An instantiation failure (e.g., a payload version mismatch) is memoized like the N-API loader's,\n * since instantiating the same module again would fail again.\n */\nexport function createWasmBinding(module: WebAssembly.Module): NativeBinding {\n let instance: { exports: WasmExports; stderr: string[] } | undefined;\n let instantiationFailure: unknown;\n\n const call = (invoke: (exports: WasmExports) => number): string => {\n if (!instance) {\n if (instantiationFailure) {\n throw instantiationFailure;\n }\n try {\n instance = instantiate(module);\n } catch (error) {\n instantiationFailure = error;\n throw error;\n }\n }\n const { exports, stderr } = instance;\n stderr.length = 0;\n let status: number;\n try {\n status = invoke(exports);\n } catch (error) {\n instance = undefined;\n throw new Error(`The code-gauge WebAssembly module crashed: ${stderr.join('').trim() || String(error)}`, {\n cause: error,\n });\n }\n const result = decoder.decode(new Uint8Array(exports.memory.buffer, exports.result_ptr(), exports.result_len()));\n if (status !== 0) {\n throw new Error(result);\n }\n return result;\n };\n\n const measureCodeNative: NativeBinding['measureCodeNative'] = (\n code,\n language,\n includeSyntaxTree,\n minTokens,\n maxGapTokens,\n minSimilarityPercent,\n includeCrossFileData\n ) =>\n call((exports) =>\n exports.measure_code(\n ...passString(exports, code),\n ...passString(exports, language),\n Number(includeSyntaxTree),\n toOptionalU32(minTokens),\n toOptionalU32(maxGapTokens),\n toOptionalU32(minSimilarityPercent),\n Number(includeCrossFileData)\n )\n );\n\n return {\n measureCodeNative,\n // The WebAssembly build has no threads, so the asynchronous form measures in place.\n measureCodeNativeAsync: async (...args) => measureCodeNative(...args),\n collectCrossFileDataNative: (code, language, minTokens) =>\n call((exports) =>\n exports.collect_cross_file_data(\n ...passString(exports, code),\n ...passString(exports, language),\n toOptionalU32(minTokens)\n )\n ),\n collectFunctionTokenSequencesNative: (code, language) =>\n call((exports) =>\n exports.collect_function_token_sequences(...passString(exports, code), ...passString(exports, language))\n ),\n };\n}\n\nfunction instantiate(module: WebAssembly.Module): { exports: WasmExports; stderr: string[] } {\n const stderr: string[] = [];\n let memory: WebAssembly.Memory | undefined;\n const instance = new WebAssembly.Instance(module, {\n wasi_snapshot_preview1: createWasiImports(() => memory as WebAssembly.Memory, stderr),\n });\n const exports = instance.exports as unknown as WasmExports;\n memory = exports.memory;\n const version = exports.payload_version();\n if (version !== expectedPayloadVersion) {\n throw new NativeAddonError(\n `The code-gauge WebAssembly module has payload version ${version}, but ${expectedPayloadVersion} is ` +\n 'expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with `bun run build-wasm`'\n );\n }\n return { exports, stderr };\n}\n\n/** Copies a string into a buffer whose ownership passes to the called export. */\nfunction passString(exports: WasmExports, text: string): [number, number] {\n // TextEncoder replaces lone surrogates with U+FFFD, like toWellFormed() does for the N-API addon.\n const bytes = encoder.encode(text);\n const pointer = exports.alloc(bytes.length);\n new Uint8Array(exports.memory.buffer, pointer, bytes.length).set(bytes);\n return [pointer, bytes.length];\n}\n\n/** native/src/wasm.rs reads a negative value as an absent setting. */\nfunction toOptionalU32(value: number | undefined): number {\n return value ?? -1;\n}\n\nconst WASI_ERRNO_SUCCESS = 0;\nconst WASI_ERRNO_BADF = 8;\n// crypto.getRandomValues() rejects requests larger than this.\nconst MAX_RANDOM_BYTES = 65_536;\n\n/**\n * The WASI preview 1 functions the module imports. The metrics code performs no I/O, so file\n * descriptors are unavailable except for writes, whose stderr output (e.g., a panic message) is\n * kept for the error raised when the module traps.\n */\nfunction createWasiImports(\n getMemory: () => WebAssembly.Memory,\n stderr: string[]\n): Record<string, (...args: never[]) => number> {\n const view = (): DataView => new DataView(getMemory().buffer);\n const unavailable = (): number => WASI_ERRNO_BADF;\n return {\n environ_get: () => WASI_ERRNO_SUCCESS,\n environ_sizes_get: (countPointer: number, sizePointer: number) => {\n view().setUint32(countPointer, 0, true);\n view().setUint32(sizePointer, 0, true);\n return WASI_ERRNO_SUCCESS;\n },\n clock_time_get: (_clockId: number, _precision: bigint, timePointer: number) => {\n view().setBigUint64(timePointer, BigInt(Date.now()) * 1_000_000n, true);\n return WASI_ERRNO_SUCCESS;\n },\n random_get: (pointer: number, length: number) => {\n for (let offset = 0; offset < length; offset += MAX_RANDOM_BYTES) {\n crypto.getRandomValues(\n new Uint8Array(getMemory().buffer, pointer + offset, Math.min(MAX_RANDOM_BYTES, length - offset))\n );\n }\n return WASI_ERRNO_SUCCESS;\n },\n fd_write: (fd: number, iovsPointer: number, iovsLength: number, writtenPointer: number) => {\n const memoryView = view();\n let written = 0;\n for (let index = 0; index < iovsLength; index++) {\n const pointer = memoryView.getUint32(iovsPointer + index * 8, true);\n const length = memoryView.getUint32(iovsPointer + index * 8 + 4, true);\n if (fd === 2) {\n stderr.push(decoder.decode(new Uint8Array(getMemory().buffer, pointer, length)));\n }\n written += length;\n }\n memoryView.setUint32(writtenPointer, written, true);\n return WASI_ERRNO_SUCCESS;\n },\n fd_close: unavailable,\n fd_fdstat_get: unavailable,\n fd_fdstat_set_flags: unavailable,\n fd_read: unavailable,\n fd_seek: unavailable,\n proc_exit: (code: number) => {\n throw new Error(`The code-gauge WebAssembly module exited with code ${code}`);\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wasmBinding.js","names":["encoder","decoder","createWasmBinding","instance","instantiationFailure","call","instantiate","module","error","status","invoke","exports","stderr","result","measureCodeNative","passString","code","language","includeSyntaxTree","toOptionalU32","minTokens","maxGapTokens","minSimilarityPercent","includeCrossFileData","args","memory","createWasiImports","version","NativeAddonError","bytes","text","pointer","value","MAX_RANDOM_BYTES","view","getMemory","countPointer","sizePointer","timePointer","offset","length","memoryView","written","index","iovsLength","iovsPointer","fd","writtenPointer","unavailable"],"sources":["../src/wasmBinding.ts"],"sourcesContent":["import { expectedPayloadVersion, NativeAddonError, type NativeBinding } from './nativeMetrics.js';\n\n/** The C ABI exported by native/src/wasm.rs. */\ninterface WasmExports {\n memory: WebAssembly.Memory;\n payload_version(): number;\n alloc(length: number): number;\n result_ptr(): number;\n result_len(): number;\n measure_code(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n includeSyntaxTree: number,\n minTokens: number,\n maxGapTokens: number,\n minSimilarityPercent: number,\n includeCrossFileData: number\n ): number;\n collect_cross_file_data(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n minTokens: number\n ): number;\n collect_function_token_sequences(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number\n ): number;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Wraps the WebAssembly build of the native addon (native/src/wasm.rs) as a NativeBinding. The\n * module is instantiated synchronously on first use and again after a trap (a panic or stack\n * overflow), because a trap leaves the instance's memory and stack pointer in an undefined state.\n * An instantiation failure (e.g., a payload version mismatch) is memoized like the N-API loader's,\n * since instantiating the same module again would fail again.\n */\nexport function createWasmBinding(module: WebAssembly.Module): NativeBinding {\n let instance: { exports: WasmExports; stderr: string[] } | undefined;\n let instantiationFailure: unknown;\n\n const call = (invoke: (exports: WasmExports) => number): string => {\n if (!instance) {\n if (instantiationFailure) {\n throw instantiationFailure;\n }\n try {\n instance = instantiate(module);\n } catch (error) {\n instantiationFailure = error;\n throw error;\n }\n }\n const { exports, stderr } = instance;\n stderr.length = 0;\n let status: number;\n try {\n status = invoke(exports);\n } catch (error) {\n instance = undefined;\n throw new Error(`The code-gauge WebAssembly module crashed: ${stderr.join('').trim() || String(error)}`, {\n cause: error,\n });\n }\n const result = decoder.decode(new Uint8Array(exports.memory.buffer, exports.result_ptr(), exports.result_len()));\n if (status !== 0) {\n throw new Error(result);\n }\n return result;\n };\n\n const measureCodeNative: NativeBinding['measureCodeNative'] = (\n code,\n language,\n includeSyntaxTree,\n minTokens,\n maxGapTokens,\n minSimilarityPercent,\n includeCrossFileData\n ) =>\n call((exports) =>\n exports.measure_code(\n ...passString(exports, code),\n ...passString(exports, language),\n Number(includeSyntaxTree),\n toOptionalU32(minTokens),\n toOptionalU32(maxGapTokens),\n toOptionalU32(minSimilarityPercent),\n Number(includeCrossFileData)\n )\n );\n\n return {\n measureCodeNative,\n // The WebAssembly build has no threads, so the asynchronous form measures in place.\n measureCodeNativeAsync: async (...args) => measureCodeNative(...args),\n collectCrossFileDataNative: (code, language, minTokens) =>\n call((exports) =>\n exports.collect_cross_file_data(\n ...passString(exports, code),\n ...passString(exports, language),\n toOptionalU32(minTokens)\n )\n ),\n collectFunctionTokenSequencesNative: (code, language) =>\n call((exports) =>\n exports.collect_function_token_sequences(...passString(exports, code), ...passString(exports, language))\n ),\n };\n}\n\nfunction instantiate(module: WebAssembly.Module): { exports: WasmExports; stderr: string[] } {\n const stderr: string[] = [];\n let memory: WebAssembly.Memory | undefined;\n const instance = new WebAssembly.Instance(module, {\n wasi_snapshot_preview1: createWasiImports(() => memory as WebAssembly.Memory, stderr),\n });\n const exports = instance.exports as unknown as WasmExports;\n memory = exports.memory;\n const version = exports.payload_version();\n if (version !== expectedPayloadVersion) {\n throw new NativeAddonError(\n `The code-gauge WebAssembly module has payload version ${version}, but ${expectedPayloadVersion} is ` +\n 'expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with `bun run build-wasm`'\n );\n }\n return { exports, stderr };\n}\n\n/** Copies a string into a buffer whose ownership passes to the called export. */\nfunction passString(exports: WasmExports, text: string): [number, number] {\n // TextEncoder replaces lone surrogates with U+FFFD, like toWellFormed() does for the N-API addon.\n const bytes = encoder.encode(text);\n const pointer = exports.alloc(bytes.length);\n new Uint8Array(exports.memory.buffer, pointer, bytes.length).set(bytes);\n return [pointer, bytes.length];\n}\n\n/** native/src/wasm.rs reads a negative value as an absent setting. */\nfunction toOptionalU32(value: number | undefined): number {\n return value ?? -1;\n}\n\nconst WASI_ERRNO_SUCCESS = 0;\nconst WASI_ERRNO_BADF = 8;\n// crypto.getRandomValues() rejects requests larger than this.\nconst MAX_RANDOM_BYTES = 65_536;\n\n/**\n * The WASI preview 1 functions the module imports. The metrics code performs no I/O, so file\n * descriptors are unavailable except for writes, whose stderr output (e.g., a panic message) is\n * kept for the error raised when the module traps.\n */\nfunction createWasiImports(\n getMemory: () => WebAssembly.Memory,\n stderr: string[]\n): Record<string, (...args: never[]) => number> {\n const view = (): DataView => new DataView(getMemory().buffer);\n return {\n environ_get: () => WASI_ERRNO_SUCCESS,\n environ_sizes_get: (countPointer: number, sizePointer: number) => {\n view().setUint32(countPointer, 0, true);\n view().setUint32(sizePointer, 0, true);\n return WASI_ERRNO_SUCCESS;\n },\n clock_time_get: (_clockId: number, _precision: bigint, timePointer: number) => {\n view().setBigUint64(timePointer, BigInt(Date.now()) * 1_000_000n, true);\n return WASI_ERRNO_SUCCESS;\n },\n random_get: (pointer: number, length: number) => {\n for (let offset = 0; offset < length; offset += MAX_RANDOM_BYTES) {\n crypto.getRandomValues(\n new Uint8Array(getMemory().buffer, pointer + offset, Math.min(MAX_RANDOM_BYTES, length - offset))\n );\n }\n return WASI_ERRNO_SUCCESS;\n },\n fd_write: (fd: number, iovsPointer: number, iovsLength: number, writtenPointer: number) => {\n const memoryView = view();\n let written = 0;\n for (let index = 0; index < iovsLength; index++) {\n const pointer = memoryView.getUint32(iovsPointer + index * 8, true);\n const length = memoryView.getUint32(iovsPointer + index * 8 + 4, true);\n if (fd === 2) {\n stderr.push(decoder.decode(new Uint8Array(getMemory().buffer, pointer, length)));\n }\n written += length;\n }\n memoryView.setUint32(writtenPointer, written, true);\n return WASI_ERRNO_SUCCESS;\n },\n fd_close: unavailable,\n fd_fdstat_get: unavailable,\n fd_fdstat_set_flags: unavailable,\n fd_read: unavailable,\n fd_seek: unavailable,\n proc_exit: (code: number) => {\n throw new Error(`The code-gauge WebAssembly module exited with code ${code}`);\n },\n };\n}\n\nfunction unavailable(): number {\n return WASI_ERRNO_BADF;\n}\n"],"mappings":"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"}
|
package/dist/worker.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.cjs","names":["setNativeBinding","createWasmBinding","wasmModule"],"sources":["../src/worker.ts"],"sourcesContent":["// The entry point for Cloudflare Workers (the `workerd` export condition), which cannot load N-API\n// addons: the same API runs on the WebAssembly build of the native addon.\nimport wasmModule from '../native/code-gauge.wasm';\nimport { setNativeBinding } from './nativeMetrics.js';\nimport { createWasmBinding } from './wasmBinding.js';\n\nsetNativeBinding(createWasmBinding(wasmModule));\n\nexport * from './index.js';\n"],"mappings":"6XAMAA,EAAAA,iBAAiBC,EAAAA,kBAAkBC,EAAAA,OAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"worker.cjs","names":["setNativeBinding","createWasmBinding","wasmModule","require_runtime","require_crossFileDuplication","require_languages","require_nativeMetrics","require_metrics","require_wasmBinding","native_code_gauge_wasm"],"sources":["../src/worker.ts"],"sourcesContent":["// The entry point for Cloudflare Workers (the `workerd` export condition), which cannot load N-API\n// addons: the same API runs on the WebAssembly build of the native addon.\nimport wasmModule from '../native/code-gauge.wasm';\nimport { setNativeBinding } from './nativeMetrics.js';\nimport { createWasmBinding } from './wasmBinding.js';\n\nsetNativeBinding(createWasmBinding(wasmModule));\n\nexport * from './index.js';\n"],"mappings":"6XAMAA,EAAAA,iBAAiBC,EAAAA,kBAAkBC,EAAAA,OAAU,CAAC"}
|
package/dist/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","names":[],"sources":["../src/worker.ts"],"sourcesContent":["// The entry point for Cloudflare Workers (the `workerd` export condition), which cannot load N-API\n// addons: the same API runs on the WebAssembly build of the native addon.\nimport wasmModule from '../native/code-gauge.wasm';\nimport { setNativeBinding } from './nativeMetrics.js';\nimport { createWasmBinding } from './wasmBinding.js';\n\nsetNativeBinding(createWasmBinding(wasmModule));\n\nexport * from './index.js';\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"worker.js","names":["wasmModule","setNativeBinding","createWasmBinding","TreeMeasurer","collectCrossFileDuplicationFileData","collectDuplicationCandidates","collectFunctionTokenSequences","defaultLanguages","defaultMeasurer","detectLanguage","measureCode","measureCrossFileDuplication","supportedLanguages"],"sources":["../src/worker.ts"],"sourcesContent":["// The entry point for Cloudflare Workers (the `workerd` export condition), which cannot load N-API\n// addons: the same API runs on the WebAssembly build of the native addon.\nimport wasmModule from '../native/code-gauge.wasm';\nimport { setNativeBinding } from './nativeMetrics.js';\nimport { createWasmBinding } from './wasmBinding.js';\n\nsetNativeBinding(createWasmBinding(wasmModule));\n\nexport * from './index.js';\n"],"mappings":"6gBAMAC,EAAiBC,EAAkBF,CAAU,CAAC"}
|
package/native/Cargo.lock
CHANGED
|
@@ -444,9 +444,9 @@ checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
|
|
|
444
444
|
|
|
445
445
|
[[package]]
|
|
446
446
|
name = "willbooster-tree-sitter"
|
|
447
|
-
version = "
|
|
447
|
+
version = "2.0.1"
|
|
448
448
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
449
|
-
checksum = "
|
|
449
|
+
checksum = "f0e4c1b0eb97a06595a2ef7923b2b10a28a34bad807c4f2f303d21eb4b54ed96"
|
|
450
450
|
dependencies = [
|
|
451
451
|
"cc",
|
|
452
452
|
"regex",
|
|
@@ -457,9 +457,9 @@ dependencies = [
|
|
|
457
457
|
|
|
458
458
|
[[package]]
|
|
459
459
|
name = "willbooster-tree-sitter-c"
|
|
460
|
-
version = "
|
|
460
|
+
version = "5.0.0"
|
|
461
461
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
462
|
-
checksum = "
|
|
462
|
+
checksum = "0a6c8c48ea72f8d1783e4cdac7d50a500bd14b46ae578ef96fff99d2653e0152"
|
|
463
463
|
dependencies = [
|
|
464
464
|
"cc",
|
|
465
465
|
"tree-sitter-language",
|
|
@@ -467,9 +467,9 @@ dependencies = [
|
|
|
467
467
|
|
|
468
468
|
[[package]]
|
|
469
469
|
name = "willbooster-tree-sitter-c-sharp"
|
|
470
|
-
version = "
|
|
470
|
+
version = "4.0.0"
|
|
471
471
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
472
|
-
checksum = "
|
|
472
|
+
checksum = "b9539ec95844d3d65db6d77680a67b95e0d4bdea7531c670cd94d1d1fc9905c3"
|
|
473
473
|
dependencies = [
|
|
474
474
|
"cc",
|
|
475
475
|
"tree-sitter-language",
|
|
@@ -477,9 +477,9 @@ dependencies = [
|
|
|
477
477
|
|
|
478
478
|
[[package]]
|
|
479
479
|
name = "willbooster-tree-sitter-cpp"
|
|
480
|
-
version = "
|
|
480
|
+
version = "3.0.0"
|
|
481
481
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
482
|
-
checksum = "
|
|
482
|
+
checksum = "d74786e7d0c88c6d0b410629a89265653d00baf34aa9c1df617fdc630911ca7b"
|
|
483
483
|
dependencies = [
|
|
484
484
|
"cc",
|
|
485
485
|
"tree-sitter-language",
|
|
@@ -487,9 +487,9 @@ dependencies = [
|
|
|
487
487
|
|
|
488
488
|
[[package]]
|
|
489
489
|
name = "willbooster-tree-sitter-go"
|
|
490
|
-
version = "
|
|
490
|
+
version = "2.0.0"
|
|
491
491
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
492
|
-
checksum = "
|
|
492
|
+
checksum = "41c5ac97ff2ddd2309013298b2d54c064a7201607cd7d34d052a6dbfd3fb7d89"
|
|
493
493
|
dependencies = [
|
|
494
494
|
"cc",
|
|
495
495
|
"tree-sitter-language",
|
|
@@ -497,9 +497,9 @@ dependencies = [
|
|
|
497
497
|
|
|
498
498
|
[[package]]
|
|
499
499
|
name = "willbooster-tree-sitter-java"
|
|
500
|
-
version = "
|
|
500
|
+
version = "2.0.0"
|
|
501
501
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
502
|
-
checksum = "
|
|
502
|
+
checksum = "36f6d73008df52a2f2062d6f636b900a35bffcff4df4f9ce8e79ee2670a50e60"
|
|
503
503
|
dependencies = [
|
|
504
504
|
"cc",
|
|
505
505
|
"tree-sitter-language",
|
|
@@ -507,9 +507,9 @@ dependencies = [
|
|
|
507
507
|
|
|
508
508
|
[[package]]
|
|
509
509
|
name = "willbooster-tree-sitter-javascript"
|
|
510
|
-
version = "
|
|
510
|
+
version = "5.0.0"
|
|
511
511
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
512
|
-
checksum = "
|
|
512
|
+
checksum = "36939d4634a283903d76b874eb04c39e84ff3f1adb904c50251b2ce2e85c0d67"
|
|
513
513
|
dependencies = [
|
|
514
514
|
"cc",
|
|
515
515
|
"tree-sitter-language",
|
|
@@ -517,9 +517,9 @@ dependencies = [
|
|
|
517
517
|
|
|
518
518
|
[[package]]
|
|
519
519
|
name = "willbooster-tree-sitter-kotlin"
|
|
520
|
-
version = "
|
|
520
|
+
version = "5.0.0"
|
|
521
521
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
522
|
-
checksum = "
|
|
522
|
+
checksum = "0cfff8b6eb5b11f12ae1efb051e337e1743e47a29a30019c8af1ed1a4ef12d5e"
|
|
523
523
|
dependencies = [
|
|
524
524
|
"cc",
|
|
525
525
|
"tree-sitter-language",
|
|
@@ -527,9 +527,9 @@ dependencies = [
|
|
|
527
527
|
|
|
528
528
|
[[package]]
|
|
529
529
|
name = "willbooster-tree-sitter-python"
|
|
530
|
-
version = "
|
|
530
|
+
version = "2.0.0"
|
|
531
531
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
532
|
-
checksum = "
|
|
532
|
+
checksum = "b1a0fd7773e48257357d4e89bceba458798f1ecf8f1348a475148c3989562167"
|
|
533
533
|
dependencies = [
|
|
534
534
|
"cc",
|
|
535
535
|
"tree-sitter-language",
|
|
@@ -537,9 +537,9 @@ dependencies = [
|
|
|
537
537
|
|
|
538
538
|
[[package]]
|
|
539
539
|
name = "willbooster-tree-sitter-ruby"
|
|
540
|
-
version = "
|
|
540
|
+
version = "2.0.0"
|
|
541
541
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
542
|
-
checksum = "
|
|
542
|
+
checksum = "53942eea1345d917886d024260232a4d073ac2a8c984cc021e28b077554d8739"
|
|
543
543
|
dependencies = [
|
|
544
544
|
"cc",
|
|
545
545
|
"tree-sitter-language",
|
|
@@ -547,9 +547,9 @@ dependencies = [
|
|
|
547
547
|
|
|
548
548
|
[[package]]
|
|
549
549
|
name = "willbooster-tree-sitter-rust"
|
|
550
|
-
version = "
|
|
550
|
+
version = "3.0.0"
|
|
551
551
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
552
|
-
checksum = "
|
|
552
|
+
checksum = "136d0e910a15bc03afe5c1aedc9b9409f40aad12bdd48b6b8074ca89af29889b"
|
|
553
553
|
dependencies = [
|
|
554
554
|
"cc",
|
|
555
555
|
"tree-sitter-language",
|
|
@@ -557,9 +557,9 @@ dependencies = [
|
|
|
557
557
|
|
|
558
558
|
[[package]]
|
|
559
559
|
name = "willbooster-tree-sitter-typescript"
|
|
560
|
-
version = "
|
|
560
|
+
version = "8.0.0"
|
|
561
561
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
562
|
-
checksum = "
|
|
562
|
+
checksum = "74c312e563df0bcb5dcc8fb6cbebd47d489423d6860aae75b4caa525b014cad8"
|
|
563
563
|
dependencies = [
|
|
564
564
|
"cc",
|
|
565
565
|
"tree-sitter-language",
|
package/native/Cargo.toml
CHANGED
|
@@ -22,18 +22,18 @@ rustc-hash = "2"
|
|
|
22
22
|
# `willbooster-*` crates are WillBooster's forks of the runtime and grammars. Every grammar crate
|
|
23
23
|
# depends only on `tree-sitter-language`, never on upstream's `tree-sitter` crate, whose
|
|
24
24
|
# `links = "tree-sitter"` would conflict with the forked runtime's.
|
|
25
|
-
tree-sitter = { package = "willbooster-tree-sitter", version = "
|
|
26
|
-
tree-sitter-c = { package = "willbooster-tree-sitter-c", version = "=
|
|
27
|
-
tree-sitter-c-sharp = { package = "willbooster-tree-sitter-c-sharp", version = "=
|
|
28
|
-
tree-sitter-cpp = { package = "willbooster-tree-sitter-cpp", version = "=
|
|
29
|
-
tree-sitter-go = { package = "willbooster-tree-sitter-go", version = "=
|
|
30
|
-
tree-sitter-java = { package = "willbooster-tree-sitter-java", version = "=
|
|
31
|
-
tree-sitter-javascript = { package = "willbooster-tree-sitter-javascript", version = "=
|
|
32
|
-
tree-sitter-kotlin = { package = "willbooster-tree-sitter-kotlin", version = "=
|
|
33
|
-
tree-sitter-python = { package = "willbooster-tree-sitter-python", version = "=
|
|
34
|
-
tree-sitter-ruby = { package = "willbooster-tree-sitter-ruby", version = "=
|
|
35
|
-
tree-sitter-rust = { package = "willbooster-tree-sitter-rust", version = "=
|
|
36
|
-
tree-sitter-typescript = { package = "willbooster-tree-sitter-typescript", version = "=
|
|
25
|
+
tree-sitter = { package = "willbooster-tree-sitter", version = "2" }
|
|
26
|
+
tree-sitter-c = { package = "willbooster-tree-sitter-c", version = "=5.0.0" }
|
|
27
|
+
tree-sitter-c-sharp = { package = "willbooster-tree-sitter-c-sharp", version = "=4.0.0" }
|
|
28
|
+
tree-sitter-cpp = { package = "willbooster-tree-sitter-cpp", version = "=3.0.0" }
|
|
29
|
+
tree-sitter-go = { package = "willbooster-tree-sitter-go", version = "=2.0.0" }
|
|
30
|
+
tree-sitter-java = { package = "willbooster-tree-sitter-java", version = "=2.0.0" }
|
|
31
|
+
tree-sitter-javascript = { package = "willbooster-tree-sitter-javascript", version = "=5.0.0" }
|
|
32
|
+
tree-sitter-kotlin = { package = "willbooster-tree-sitter-kotlin", version = "=5.0.0" }
|
|
33
|
+
tree-sitter-python = { package = "willbooster-tree-sitter-python", version = "=2.0.0" }
|
|
34
|
+
tree-sitter-ruby = { package = "willbooster-tree-sitter-ruby", version = "=2.0.0" }
|
|
35
|
+
tree-sitter-rust = { package = "willbooster-tree-sitter-rust", version = "=3.0.0" }
|
|
36
|
+
tree-sitter-typescript = { package = "willbooster-tree-sitter-typescript", version = "=8.0.0" }
|
|
37
37
|
|
|
38
38
|
# The WebAssembly build (src/wasm.rs) exports a plain C ABI instead of N-API.
|
|
39
39
|
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
package/native/code-gauge.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-gauge",
|
|
3
|
-
"version": "10.2.
|
|
3
|
+
"version": "10.2.4",
|
|
4
4
|
"description": "Measure code metrics with tree-sitter.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -72,13 +72,13 @@
|
|
|
72
72
|
"@types/node": "25.9.4",
|
|
73
73
|
"@willbooster/oxfmt-config": "1.2.2",
|
|
74
74
|
"@willbooster/oxlint-config": "1.4.8",
|
|
75
|
-
"@willbooster/wb": "22.
|
|
76
|
-
"build-ts": "21.0.
|
|
75
|
+
"@willbooster/wb": "22.24.0",
|
|
76
|
+
"build-ts": "21.0.25",
|
|
77
77
|
"conventional-changelog-conventionalcommits": "9.3.1",
|
|
78
|
-
"lefthook": "2.1.
|
|
79
|
-
"oxfmt": "0.
|
|
80
|
-
"oxlint": "1.
|
|
81
|
-
"oxlint-tsgolint": "7.0.
|
|
78
|
+
"lefthook": "2.1.16",
|
|
79
|
+
"oxfmt": "0.71.0",
|
|
80
|
+
"oxlint": "1.86.0",
|
|
81
|
+
"oxlint-tsgolint": "7.0.2003",
|
|
82
82
|
"semantic-release": "25.0.5",
|
|
83
83
|
"sort-package-json": "4.0.0",
|
|
84
84
|
"typescript": "7.0.2",
|
|
@@ -93,12 +93,12 @@
|
|
|
93
93
|
"registry": "https://registry.npmjs.org/"
|
|
94
94
|
},
|
|
95
95
|
"optionalDependencies": {
|
|
96
|
-
"code-gauge-linux-x64-gnu": "10.2.
|
|
97
|
-
"code-gauge-linux-arm64-gnu": "10.2.
|
|
98
|
-
"code-gauge-linux-x64-musl": "10.2.
|
|
99
|
-
"code-gauge-linux-arm64-musl": "10.2.
|
|
100
|
-
"code-gauge-darwin-x64": "10.2.
|
|
101
|
-
"code-gauge-darwin-arm64": "10.2.
|
|
102
|
-
"code-gauge-win32-x64-msvc": "10.2.
|
|
96
|
+
"code-gauge-linux-x64-gnu": "10.2.4",
|
|
97
|
+
"code-gauge-linux-arm64-gnu": "10.2.4",
|
|
98
|
+
"code-gauge-linux-x64-musl": "10.2.4",
|
|
99
|
+
"code-gauge-linux-arm64-musl": "10.2.4",
|
|
100
|
+
"code-gauge-darwin-x64": "10.2.4",
|
|
101
|
+
"code-gauge-darwin-arm64": "10.2.4",
|
|
102
|
+
"code-gauge-win32-x64-msvc": "10.2.4"
|
|
103
103
|
}
|
|
104
104
|
}
|