@tgwf/co2 0.16.8 → 0.17.0
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/CHANGELOG.md +10 -0
- package/CONTRIBUTING.md +1 -0
- package/README.md +2 -1
- package/dist/cjs/co2.js +7 -0
- package/dist/cjs/co2.js.map +2 -2
- package/dist/cjs/data/average-intensities.min.js +1 -1
- package/dist/cjs/data/average-intensities.min.js.map +2 -2
- package/dist/cjs/data.js +38 -0
- package/dist/cjs/data.js.map +7 -0
- package/dist/cjs/helpers/index.js +1 -1
- package/dist/cjs/hosting-node.js +1 -0
- package/dist/cjs/hosting-node.js.map +2 -2
- package/dist/cjs/hosting.js +1 -0
- package/dist/cjs/hosting.js.map +2 -2
- package/dist/cjs/sustainable-web-design.js +249 -0
- package/dist/cjs/sustainable-web-design.js.map +7 -0
- package/dist/esm/co2.js +2 -0
- package/dist/esm/data/average-intensities.min.js +1 -1
- package/dist/esm/data.js +8 -0
- package/dist/esm/helpers/index.js +1 -1
- package/dist/esm/hosting.js +1 -0
- package/dist/esm/sustainable-web-design.js +259 -0
- package/package.json +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -21,6 +21,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
21
21
|
|
|
22
22
|
## Released
|
|
23
23
|
|
|
24
|
+
### [0.16.8] - 2025-05-12
|
|
25
|
+
|
|
26
|
+
#### Fixed
|
|
27
|
+
|
|
28
|
+
- Corrected the implementation of `dataReloadRatio` in Sustainable Web Design Model v4 to be a multiplier rather than the inverse.
|
|
29
|
+
|
|
30
|
+
#### Changed
|
|
31
|
+
|
|
32
|
+
- Automated monthly update of annual average grid intensity data.
|
|
33
|
+
|
|
24
34
|
### [0.16.7] - 2025-04-18
|
|
25
35
|
|
|
26
36
|
#### Changed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -27,6 +27,7 @@ Thank you for considering contributing to CO2.js. Open source is at the heart of
|
|
|
27
27
|
|
|
28
28
|
- Push the changes made in your branch to your fork of this repository.
|
|
29
29
|
- Submit a [pull request](https://github.com/thegreenwebfoundation/co2.js/pulls) to the CO2.js repository in the `thegreenwebfoundation` organization.
|
|
30
|
+
- Please ensure that you *only* merge any pull requests into the `next` branch of this repo.
|
|
30
31
|
- When opening a new pull request, you'll see a template. Please follow it. It asks you to state:
|
|
31
32
|
- the type of change (choose from a list)
|
|
32
33
|
- link to the related issue
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
One day, the internet will be powered by renewable energy. Until that day comes, there’ll be a CO2 cost that comes with every byte of data that’s uploaded or downloaded. By being able to calculate these emissions, developers can be empowered to create more efficient, lower carbon apps, websites, and software.
|
|
12
12
|
|
|
13
|
-
## [Documentation](https://developers.thegreenwebfoundation.org/co2js/overview/) | [Changelog](/CHANGELOG.md) | [Roadmap](https://
|
|
13
|
+
## [Documentation](https://developers.thegreenwebfoundation.org/co2js/overview/) | [Changelog](/CHANGELOG.md) | [Roadmap](https://developers.thegreenwebfoundation.org/co2js/roadmap/)
|
|
14
14
|
|
|
15
15
|
## What is CO2.js?
|
|
16
16
|
|
|
@@ -122,6 +122,7 @@ CO2.js releases will be communicated through the following channels:
|
|
|
122
122
|
| W3C Slack Sustainability Channel | ✅ | ❌ |
|
|
123
123
|
| ClimateAction.Tech Slack | ✅ | ❌ |
|
|
124
124
|
| [Green Web Foundation LinkedIn Account](https://www.linkedin.com/company/green-web-foundation/) | ✅ | ❌ |
|
|
125
|
+
| [CO2.js Mailing List](https://www.thegreenwebfoundation.org/co2-js/#stay-updated) | ✅ | ❌ |
|
|
125
126
|
|
|
126
127
|
## Licenses
|
|
127
128
|
|
package/dist/cjs/co2.js
CHANGED
|
@@ -46,6 +46,13 @@ class CO2 {
|
|
|
46
46
|
if ((options == null ? void 0 : options.version) === 4) {
|
|
47
47
|
this.model = new import_sustainable_web_design_v4.default();
|
|
48
48
|
}
|
|
49
|
+
} else if (!(options == null ? void 0 : options.model)) {
|
|
50
|
+
console.warn(`------
|
|
51
|
+
WARNING: We are changing the default estimation model in CO2.js to Sustainable Web Design v4 in the next version (v0.18) of CO2.js. This change will take place in February 2026.
|
|
52
|
+
|
|
53
|
+
If you would like to keep using Sustainable Web Design v3, please make sure to explicitly set it in your code. See https://developers.thegreenwebfoundation.org/co2js/models/#using-sustainable-web-design-model-version-3 for details.
|
|
54
|
+
------
|
|
55
|
+
`);
|
|
49
56
|
} else if (options == null ? void 0 : options.model) {
|
|
50
57
|
throw new Error(
|
|
51
58
|
`"${options.model}" is not a valid model. Please use "1byte" for the OneByte model, and "swd" for the Sustainable Web Design model.
|
package/dist/cjs/co2.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/co2.js"],
|
|
4
|
-
"sourcesContent": ["\"use strict\";\n\n/**\n * @typedef {Object} CO2EstimateTraceResultPerByte\n * @property {number|CO2EstimateComponentsPerByte} co2 - The CO2 estimate in grams or its separate components\n * @property {boolean} green - Whether the domain is green or not\n * @property {TraceResultVariablesPerByte} variables - The variables used to calculate the CO2 estimate\n */\n\n/**\n * @typedef {Object} CO2EstimateTraceResultPerVisit\n * @property {number|CO2EstimateComponentsPerVisit} co2 - The CO2 estimate in grams or its separate components\n * @property {boolean} green - Whether the domain is green or not\n * @property {TraceResultVariablesPerVisit} variables - The variables used to calculate the CO2 estimate\n */\n\n/**\n * @typedef {Object} TraceResultVariablesPerByte\n * @property {GridIntensityVariables} gridIntensity - The grid intensity related variables\n */\n/**\n * @typedef {Object} TraceResultVariablesPerVisit\n * @property {GridIntensityVariables} gridIntensity - The grid intensity related variables\n * @property {number} dataReloadRatio - What percentage of a page is reloaded on each subsequent page view\n * @property {number} firstVisitPercentage - What percentage of visits are loading this page for subsequent times\n * @property {number} returnVisitPercentage - What percentage of visits are loading this page for the second or more time\n */\n\n/**\n * @typedef {Object} GridIntensityVariables\n * @property {string} description - The description of the variables\n * @property {number} network - The network grid intensity set by the user or the default\n * @property {number} dataCenter - The data center grid intensity set by the user or the default\n * @property {number} device - The device grid intensity set by the user or the default\n * @property {number} production - The production grid intensity set by the user or the default\n */\n\n/**\n * @typedef {Object} CO2EstimateComponentsPerByte\n * @property {number} networkCO2 - The CO2 estimate for networking in grams\n * @property {number} dataCenterCO2 - The CO2 estimate for data centers in grams\n * @property {number} consumerDeviceCO2 - The CO2 estimate for consumer devices in grams\n * @property {number} productionCO2 - The CO2 estimate for device production in grams\n * @property {string} rating - The rating of the CO2 estimate based on the Sustainable Web Design Model\n * @property {number} total - The total CO2 estimate in grams\n */\n\n/**\n * @typedef {Object} CO2EstimateComponentsPerVisit\n * @property {number} 'networkCO2 - first' - The CO2 estimate for networking in grams on first visit\n * @property {number} 'networkCO2 - subsequent' - The CO2 estimate for networking in grams on subsequent visits\n * @property {number} 'dataCenterCO2 - first' - The CO2 estimate for data centers in grams on first visit\n * @property {number} 'dataCenterCO2 - subsequent' - The CO2 estimate for data centers in grams on subsequent visits\n * @property {number} 'consumerDeviceCO2 - first' - The CO2 estimate for consumer devices in grams on first visit\n * @property {number} 'consumerDeviceCO2 - subsequent' - The CO2 estimate for consumer devices in grams on subsequent visits\n * @property {number} 'productionCO2 - first' - The CO2 estimate for device production in grams on first visit\n * @property {number} 'productionCO2 - subsequent' - The CO2 estimate for device production in grams on subsequent visits\n * @property {string} rating - The rating of the CO2 estimate based on the Sustainable Web Design Model\n * @property {number} total - The total CO2 estimate in grams\n */\n\nimport OneByte from \"./1byte.js\";\nimport SustainableWebDesignV3 from \"./sustainable-web-design-v3.js\";\nimport SustainableWebDesignV4 from \"./sustainable-web-design-v4.js\";\n\nimport {\n parseByteTraceOptions,\n parseVisitTraceOptions,\n} from \"./helpers/index.js\";\n\nclass CO2 {\n constructor(options) {\n this.model = new SustainableWebDesignV3();\n // Using optional chaining allows an empty object to be passed\n // in without breaking the code.\n if (options?.model === \"1byte\") {\n this.model = new OneByte();\n } else if (options?.model === \"swd\") {\n this.model = new SustainableWebDesignV3();\n if (options?.version === 4) {\n this.model = new SustainableWebDesignV4();\n }\n } else if (options?.model) {\n throw new Error(\n `\"${options.model}\" is not a valid model. Please use \"1byte\" for the OneByte model, and \"swd\" for the Sustainable Web Design model.\\nSee https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.`\n );\n }\n\n if (options?.rating && typeof options.rating !== \"boolean\") {\n throw new Error(\n `The rating option must be a boolean. Please use true or false.\\nSee https://developers.thegreenwebfoundation.org/co2js/options/ to learn more about the options available in CO2.js.`\n );\n }\n\n // This flag checks to see if the model itself has a rating system.\n const allowRatings = !!this.model.allowRatings;\n\n /** @private */\n this._segment = options?.results === \"segment\";\n // This flag is set by the user to enable the rating system.\n this._rating = options?.rating === true;\n\n // The rating system is only supported in the Sustainable Web Design Model.\n if (!allowRatings && this._rating) {\n throw new Error(\n `The rating system is not supported in the model you are using. Try using the Sustainable Web Design model instead.\\nSee https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.`\n );\n }\n }\n\n /**\n * Accept a figure in bytes for data transfer, and a boolean for whether\n * the domain shows as 'green', and return a CO2 figure for energy used to shift the corresponding\n * the data transfer.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @return {number|CO2EstimateComponentsPerByte} the amount of CO2 in grammes or its separate components\n */\n perByte(bytes, green = false) {\n return this.model.perByte(bytes, green, this._segment, this._rating);\n }\n\n /**\n * Accept a figure in bytes for data transfer, and a boolean for whether\n * the domain shows as 'green', and return a CO2 figure for energy used to shift the corresponding\n * the data transfer.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @return {number|CO2EstimateComponentsPerVisit} the amount of CO2 in grammes or its separate components\n */\n perVisit(bytes, green = false) {\n if (this.model?.perVisit) {\n return this.model.perVisit(bytes, green, this._segment, this._rating);\n } else {\n throw new Error(\n `The perVisit() method is not supported in the model you are using. Try using perByte() instead.\\nSee https://developers.thegreenwebfoundation.org/co2js/methods/ to learn more about the methods available in CO2.js.`\n );\n }\n }\n\n /**\n * Accept a figure in bytes for data transfer, a boolean for whether\n * the domain shows as 'green', and an options object.\n * Returns an object containing CO2 figure, green boolean, and object of the variables used in calculating the CO2 figure.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @param {Object} options\n * @return {CO2EstimateTraceResultPerByte} the amount of CO2 in grammes\n */\n perByteTrace(bytes, green = false, options = {}) {\n const adjustments = parseByteTraceOptions(\n options,\n this.model.version,\n green\n );\n\n // Filter out the trace items that aren't relevant to this function.\n const { gridIntensity, ...traceVariables } = adjustments;\n const {\n dataReloadRatio,\n firstVisitPercentage,\n returnVisitPercentage,\n ...otherVariables\n } = traceVariables;\n return {\n co2: this.model.perByte(\n bytes,\n green,\n this._segment,\n this._rating,\n adjustments\n ),\n green,\n variables: {\n description:\n \"Below are the variables used to calculate this CO2 estimate.\",\n bytes,\n gridIntensity: {\n description:\n \"The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate.\",\n ...adjustments.gridIntensity,\n },\n ...otherVariables,\n },\n };\n }\n\n /**\n * Accept a figure in bytes for data transfer, a boolean for whether\n * the domain shows as 'green', and an options object.\n * Returns an object containing CO2 figure, green boolean, and object of the variables used in calculating the CO2 figure.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @param {Object} options\n * @return {CO2EstimateTraceResultPerVisit} the amount of CO2 in grammes\n */\n perVisitTrace(bytes, green = false, options = {}) {\n if (this.model?.perVisit) {\n const adjustments = parseVisitTraceOptions(\n options,\n this.model.version,\n green\n );\n const { gridIntensity, ...variables } = adjustments;\n\n return {\n co2: this.model.perVisit(\n bytes,\n green,\n this._segment,\n this._rating,\n adjustments\n ),\n green,\n variables: {\n description:\n \"Below are the variables used to calculate this CO2 estimate.\",\n bytes,\n gridIntensity: {\n description:\n \"The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate.\",\n ...adjustments.gridIntensity,\n },\n ...variables,\n },\n };\n } else {\n throw new Error(\n `The perVisitTrace() method is not supported in the model you are using. Try using perByte() instead.\\nSee https://developers.thegreenwebfoundation.org/co2js/methods/ to learn more about the methods available in CO2.js.`\n );\n }\n }\n\n SustainableWebDesignV3() {\n return new SustainableWebDesignV3();\n }\n\n SustainableWebDesignV4() {\n return new SustainableWebDesignV4();\n }\n\n OneByte() {\n return new OneByte();\n }\n}\n\nexport { CO2 };\nexport default CO2;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6DA,kBAAoB;AACpB,uCAAmC;AACnC,uCAAmC;AAEnC,qBAGO;AAEP,MAAM,IAAI;AAAA,EACR,YAAY,SAAS;AACnB,SAAK,QAAQ,IAAI,iCAAAA,QAAuB;AAGxC,SAAI,mCAAS,WAAU,SAAS;AAC9B,WAAK,QAAQ,IAAI,YAAAC,QAAQ;AAAA,IAC3B,YAAW,mCAAS,WAAU,OAAO;AACnC,WAAK,QAAQ,IAAI,iCAAAD,QAAuB;AACxC,WAAI,mCAAS,aAAY,GAAG;AAC1B,aAAK,QAAQ,IAAI,iCAAAE,QAAuB;AAAA,MAC1C;AAAA,IACF,WAAW,mCAAS,OAAO;AACzB,YAAM,IAAI;AAAA,QACR,IAAI,QAAQ,KAAK;AAAA;AAAA,MACnB;AAAA,IACF;AAEA,SAAI,mCAAS,WAAU,OAAO,QAAQ,WAAW,WAAW;AAC1D,YAAM,IAAI;AAAA,QACR;AAAA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,eAAe,CAAC,CAAC,KAAK,MAAM;AAGlC,SAAK,YAAW,mCAAS,aAAY;AAErC,SAAK,WAAU,mCAAS,YAAW;AAGnC,QAAI,CAAC,gBAAgB,KAAK,SAAS;AACjC,YAAM,IAAI;AAAA,QACR;AAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAQ,OAAO,QAAQ,OAAO;AAC5B,WAAO,KAAK,MAAM,QAAQ,OAAO,OAAO,KAAK,UAAU,KAAK,OAAO;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,SAAS,OAAO,QAAQ,OAAO;
|
|
4
|
+
"sourcesContent": ["\"use strict\";\n\n/**\n * @typedef {Object} CO2EstimateTraceResultPerByte\n * @property {number|CO2EstimateComponentsPerByte} co2 - The CO2 estimate in grams or its separate components\n * @property {boolean} green - Whether the domain is green or not\n * @property {TraceResultVariablesPerByte} variables - The variables used to calculate the CO2 estimate\n */\n\n/**\n * @typedef {Object} CO2EstimateTraceResultPerVisit\n * @property {number|CO2EstimateComponentsPerVisit} co2 - The CO2 estimate in grams or its separate components\n * @property {boolean} green - Whether the domain is green or not\n * @property {TraceResultVariablesPerVisit} variables - The variables used to calculate the CO2 estimate\n */\n\n/**\n * @typedef {Object} TraceResultVariablesPerByte\n * @property {GridIntensityVariables} gridIntensity - The grid intensity related variables\n */\n/**\n * @typedef {Object} TraceResultVariablesPerVisit\n * @property {GridIntensityVariables} gridIntensity - The grid intensity related variables\n * @property {number} dataReloadRatio - What percentage of a page is reloaded on each subsequent page view\n * @property {number} firstVisitPercentage - What percentage of visits are loading this page for subsequent times\n * @property {number} returnVisitPercentage - What percentage of visits are loading this page for the second or more time\n */\n\n/**\n * @typedef {Object} GridIntensityVariables\n * @property {string} description - The description of the variables\n * @property {number} network - The network grid intensity set by the user or the default\n * @property {number} dataCenter - The data center grid intensity set by the user or the default\n * @property {number} device - The device grid intensity set by the user or the default\n * @property {number} production - The production grid intensity set by the user or the default\n */\n\n/**\n * @typedef {Object} CO2EstimateComponentsPerByte\n * @property {number} networkCO2 - The CO2 estimate for networking in grams\n * @property {number} dataCenterCO2 - The CO2 estimate for data centers in grams\n * @property {number} consumerDeviceCO2 - The CO2 estimate for consumer devices in grams\n * @property {number} productionCO2 - The CO2 estimate for device production in grams\n * @property {string} rating - The rating of the CO2 estimate based on the Sustainable Web Design Model\n * @property {number} total - The total CO2 estimate in grams\n */\n\n/**\n * @typedef {Object} CO2EstimateComponentsPerVisit\n * @property {number} 'networkCO2 - first' - The CO2 estimate for networking in grams on first visit\n * @property {number} 'networkCO2 - subsequent' - The CO2 estimate for networking in grams on subsequent visits\n * @property {number} 'dataCenterCO2 - first' - The CO2 estimate for data centers in grams on first visit\n * @property {number} 'dataCenterCO2 - subsequent' - The CO2 estimate for data centers in grams on subsequent visits\n * @property {number} 'consumerDeviceCO2 - first' - The CO2 estimate for consumer devices in grams on first visit\n * @property {number} 'consumerDeviceCO2 - subsequent' - The CO2 estimate for consumer devices in grams on subsequent visits\n * @property {number} 'productionCO2 - first' - The CO2 estimate for device production in grams on first visit\n * @property {number} 'productionCO2 - subsequent' - The CO2 estimate for device production in grams on subsequent visits\n * @property {string} rating - The rating of the CO2 estimate based on the Sustainable Web Design Model\n * @property {number} total - The total CO2 estimate in grams\n */\n\nimport OneByte from \"./1byte.js\";\nimport SustainableWebDesignV3 from \"./sustainable-web-design-v3.js\";\nimport SustainableWebDesignV4 from \"./sustainable-web-design-v4.js\";\n\nimport {\n parseByteTraceOptions,\n parseVisitTraceOptions,\n} from \"./helpers/index.js\";\n\nclass CO2 {\n constructor(options) {\n this.model = new SustainableWebDesignV3();\n // Using optional chaining allows an empty object to be passed\n // in without breaking the code.\n if (options?.model === \"1byte\") {\n this.model = new OneByte();\n } else if (options?.model === \"swd\") {\n this.model = new SustainableWebDesignV3();\n if (options?.version === 4) {\n this.model = new SustainableWebDesignV4();\n }\n } else if (!options?.model) {\n console.warn(`------\nWARNING: We are changing the default estimation model in CO2.js to Sustainable Web Design v4 in the next version (v0.18) of CO2.js. This change will take place in February 2026.\n\nIf you would like to keep using Sustainable Web Design v3, please make sure to explicitly set it in your code. See https://developers.thegreenwebfoundation.org/co2js/models/#using-sustainable-web-design-model-version-3 for details.\n------\n `);\n } else if (options?.model) {\n throw new Error(\n `\"${options.model}\" is not a valid model. Please use \"1byte\" for the OneByte model, and \"swd\" for the Sustainable Web Design model.\\nSee https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.`\n );\n }\n\n if (options?.rating && typeof options.rating !== \"boolean\") {\n throw new Error(\n `The rating option must be a boolean. Please use true or false.\\nSee https://developers.thegreenwebfoundation.org/co2js/options/ to learn more about the options available in CO2.js.`\n );\n }\n\n // This flag checks to see if the model itself has a rating system.\n const allowRatings = !!this.model.allowRatings;\n\n /** @private */\n this._segment = options?.results === \"segment\";\n // This flag is set by the user to enable the rating system.\n this._rating = options?.rating === true;\n\n // The rating system is only supported in the Sustainable Web Design Model.\n if (!allowRatings && this._rating) {\n throw new Error(\n `The rating system is not supported in the model you are using. Try using the Sustainable Web Design model instead.\\nSee https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.`\n );\n }\n }\n\n /**\n * Accept a figure in bytes for data transfer, and a boolean for whether\n * the domain shows as 'green', and return a CO2 figure for energy used to shift the corresponding\n * the data transfer.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @return {number|CO2EstimateComponentsPerByte} the amount of CO2 in grammes or its separate components\n */\n perByte(bytes, green = false) {\n return this.model.perByte(bytes, green, this._segment, this._rating);\n }\n\n /**\n * Accept a figure in bytes for data transfer, and a boolean for whether\n * the domain shows as 'green', and return a CO2 figure for energy used to shift the corresponding\n * the data transfer.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @return {number|CO2EstimateComponentsPerVisit} the amount of CO2 in grammes or its separate components\n */\n perVisit(bytes, green = false) {\n if (this.model?.perVisit) {\n return this.model.perVisit(bytes, green, this._segment, this._rating);\n } else {\n throw new Error(\n `The perVisit() method is not supported in the model you are using. Try using perByte() instead.\\nSee https://developers.thegreenwebfoundation.org/co2js/methods/ to learn more about the methods available in CO2.js.`\n );\n }\n }\n\n /**\n * Accept a figure in bytes for data transfer, a boolean for whether\n * the domain shows as 'green', and an options object.\n * Returns an object containing CO2 figure, green boolean, and object of the variables used in calculating the CO2 figure.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @param {Object} options\n * @return {CO2EstimateTraceResultPerByte} the amount of CO2 in grammes\n */\n perByteTrace(bytes, green = false, options = {}) {\n const adjustments = parseByteTraceOptions(\n options,\n this.model.version,\n green\n );\n\n // Filter out the trace items that aren't relevant to this function.\n const { gridIntensity, ...traceVariables } = adjustments;\n const {\n dataReloadRatio,\n firstVisitPercentage,\n returnVisitPercentage,\n ...otherVariables\n } = traceVariables;\n return {\n co2: this.model.perByte(\n bytes,\n green,\n this._segment,\n this._rating,\n adjustments\n ),\n green,\n variables: {\n description:\n \"Below are the variables used to calculate this CO2 estimate.\",\n bytes,\n gridIntensity: {\n description:\n \"The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate.\",\n ...adjustments.gridIntensity,\n },\n ...otherVariables,\n },\n };\n }\n\n /**\n * Accept a figure in bytes for data transfer, a boolean for whether\n * the domain shows as 'green', and an options object.\n * Returns an object containing CO2 figure, green boolean, and object of the variables used in calculating the CO2 figure.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @param {Object} options\n * @return {CO2EstimateTraceResultPerVisit} the amount of CO2 in grammes\n */\n perVisitTrace(bytes, green = false, options = {}) {\n if (this.model?.perVisit) {\n const adjustments = parseVisitTraceOptions(\n options,\n this.model.version,\n green\n );\n const { gridIntensity, ...variables } = adjustments;\n\n return {\n co2: this.model.perVisit(\n bytes,\n green,\n this._segment,\n this._rating,\n adjustments\n ),\n green,\n variables: {\n description:\n \"Below are the variables used to calculate this CO2 estimate.\",\n bytes,\n gridIntensity: {\n description:\n \"The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate.\",\n ...adjustments.gridIntensity,\n },\n ...variables,\n },\n };\n } else {\n throw new Error(\n `The perVisitTrace() method is not supported in the model you are using. Try using perByte() instead.\\nSee https://developers.thegreenwebfoundation.org/co2js/methods/ to learn more about the methods available in CO2.js.`\n );\n }\n }\n\n SustainableWebDesignV3() {\n return new SustainableWebDesignV3();\n }\n\n SustainableWebDesignV4() {\n return new SustainableWebDesignV4();\n }\n\n OneByte() {\n return new OneByte();\n }\n}\n\nexport { CO2 };\nexport default CO2;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["SustainableWebDesignV3", "OneByte", "SustainableWebDesignV4"]
|
|
7
7
|
}
|
|
@@ -22,7 +22,7 @@ __export(average_intensities_min_exports, {
|
|
|
22
22
|
type: () => type
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(average_intensities_min_exports);
|
|
25
|
-
const data = { "AFG": 123.71, "AFRICA":
|
|
25
|
+
const data = { "AFG": 123.71, "AFRICA": 545.09, "ALB": 24.42, "DZA": 633.65, "ASM": 647.06, "AGO": 167.22, "ATG": 611.11, "ARG": 344.83, "ARM": 243.52, "ABW": 550, "ASEAN": 573.65, "ASIA": 572.12, "AUS": 553.76, "AUT": 102.62, "AZE": 632.89, "BHS": 653.66, "BHR": 902.41, "BGD": 694.63, "BRB": 600, "BLR": 323.63, "BEL": 117.58, "BLZ": 155.56, "BEN": 590, "BTN": 24.19, "BOL": 468.02, "BIH": 638.05, "BWA": 849.42, "BRA": 106.06, "BRN": 892.67, "BGR": 264.21, "BFA": 554.91, "BDI": 230.77, "CPV": 480, "KHM": 497.46, "CMR": 285.71, "CAN": 184.99, "CYM": 642.86, "CAF": 0, "TCD": 615.39, "CHL": 265.52, "CHN": 557.5, "COL": 285.8, "COM": 642.86, "COG": 713.73, "COD": 27.04, "COK": 250, "CRI": 63.01, "CIV": 393.53, "HRV": 174.48, "CUB": 638.98, "CYP": 512.24, "CZE": 413.86, "DNK": 143.3, "DJI": 450, "DMA": 600, "DOM": 565.97, "ECU": 209.7, "EGY": 574.5, "SLV": 99.29, "GNQ": 605.1, "ERI": 590.91, "EST": 341.02, "SWZ": 142.86, "ETH": 23.55, "EU": 213.02, "EUROPE": 285, "FLK": 1e3, "FRO": 354.17, "FJI": 278.26, "FIN": 72.25, "FRA": 44.18, "GUF": 204.08, "PYF": 436.62, "G20": 468.38, "G7": 343.3, "GAB": 429.47, "GMB": 666.67, "GEO": 143.06, "DEU": 342.06, "GHA": 452.86, "GRC": 319.76, "GRL": 111.11, "GRD": 666.67, "GLP": 493.9, "GUM": 611.11, "GTM": 272.66, "GIN": 182.72, "GNB": 625, "GUY": 634.33, "HTI": 534.65, "HND": 289.5, "HKG": 681.99, "HUN": 182.82, "ISL": 28.33, "IND": 708.96, "IDN": 682.43, "IRN": 648.68, "IRQ": 689.4, "IRL": 279.79, "ISR": 567.26, "ITA": 287.75, "JAM": 561.25, "JPN": 483.73, "JOR": 539.21, "KAZ": 801.79, "KEN": 84.83, "KIR": 500, "XKX": 958.72, "KWT": 637.24, "KGZ": 152.65, "LAO": 232.12, "LATIN AMERICA AND CARIBBEAN": 254.21, "LVA": 136.22, "LBN": 369.47, "LSO": 20.83, "LBR": 435.9, "LBY": 830.53, "LTU": 139.34, "LUX": 134.62, "MAC": 448.98, "MDG": 477.27, "MWI": 54.65, "MYS": 604.43, "MDV": 611.77, "MLI": 394.5, "MLT": 484.16, "MTQ": 516.78, "MRT": 481.71, "MUS": 633.03, "MEX": 483.14, "MIDDLE EAST": 637.24, "MDA": 629.56, "MNG": 784.01, "MNE": 413.51, "MSR": 1e3, "MAR": 577.65, "MOZ": 127.81, "MMR": 569.69, "NAM": 47.62, "NRU": 750, "NPL": 23.36, "NLD": 252.7, "NCL": 585.76, "NZL": 120.11, "NIC": 288.33, "NER": 687.5, "NGA": 507.85, "NORTH AMERICA": 358.36, "PRK": 344.26, "MKD": 568.97, "NOR": 30.75, "OCEANIA": 495.47, "OECD": 337.99, "OMN": 545.33, "PAK": 398.61, "PSE": 460.78, "PAN": 258.74, "PNG": 513.74, "PRY": 24.86, "PER": 263.27, "POL": 614.98, "PRT": 111.8, "PRI": 664.53, "QAT": 602.83, "REU": 525.22, "ROU": 245.55, "RUS": 446.17, "RWA": 301.89, "KNA": 636.36, "LCA": 650, "SPM": 600, "VCT": 600, "WSM": 400, "STP": 555.56, "SAU": 691.95, "SEN": 535.4, "SRB": 670.8, "SYC": 571.43, "SLE": 47.62, "SGP": 498.74, "SVK": 96.49, "SVN": 227.11, "SLB": 636.36, "SOM": 523.81, "ZAF": 713.9, "KOR": 415.65, "SSD": 610.17, "ESP": 146.15, "LKA": 509.78, "SDN": 214.33, "SUR": 383.18, "SWE": 35.89, "CHE": 36.72, "SYR": 682.27, "TWN": 635.15, "TJK": 98.7, "TZA": 371.59, "THA": 555.43, "PHL": 613.38, "TGO": 478.26, "TON": 571.43, "TTO": 682.11, "TUN": 560.25, "TUR": 469.7, "TKM": 1306.3, "TCA": 653.85, "UGA": 57.39, "UKR": 250.47, "ARE": 467.51, "GBR": 215.79, "USA": 383.55, "URY": 96.7, "UZB": 1121.18, "VUT": 500, "VEN": 180.25, "VNM": 486.13, "VGB": 647.06, "VIR": 641.79, "WORLD": 472.94, "YEM": 586.32, "ZMB": 111, "ZWE": 298.44 };
|
|
26
26
|
const type = "average";
|
|
27
27
|
var average_intensities_min_default = { data, type };
|
|
28
28
|
//# sourceMappingURL=average-intensities.min.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/data/average-intensities.min.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Minified average CO2 emissions intensity data for countries.\n * @generated Generated by generate_average_co2.js\n * @version 1.0.0\n*/\n/**\n * @constant {Object.<string, number>} data - Average CO2 emissions intensity data for various countries.\n * @constant {string} type - Type of data being represented.\n */\n const data = {\"AFG\":123.71,\"AFRICA\":
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASM,MAAM,OAAO,EAAC,OAAM,QAAO,UAAS,QAAO,OAAM,OAAM,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,KAAI,SAAQ,QAAO,QAAO,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,KAAI,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,KAAI,OAAM,OAAM,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,KAAI,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,QAAO,OAAM,GAAE,OAAM,QAAO,OAAM,QAAO,OAAM,
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Minified average CO2 emissions intensity data for countries.\n * @generated Generated by generate_average_co2.js\n * @version 1.0.0\n*/\n/**\n * @constant {Object.<string, number>} data - Average CO2 emissions intensity data for various countries.\n * @constant {string} type - Type of data being represented.\n */\n const data = {\"AFG\":123.71,\"AFRICA\":545.09,\"ALB\":24.42,\"DZA\":633.65,\"ASM\":647.06,\"AGO\":167.22,\"ATG\":611.11,\"ARG\":344.83,\"ARM\":243.52,\"ABW\":550,\"ASEAN\":573.65,\"ASIA\":572.12,\"AUS\":553.76,\"AUT\":102.62,\"AZE\":632.89,\"BHS\":653.66,\"BHR\":902.41,\"BGD\":694.63,\"BRB\":600,\"BLR\":323.63,\"BEL\":117.58,\"BLZ\":155.56,\"BEN\":590,\"BTN\":24.19,\"BOL\":468.02,\"BIH\":638.05,\"BWA\":849.42,\"BRA\":106.06,\"BRN\":892.67,\"BGR\":264.21,\"BFA\":554.91,\"BDI\":230.77,\"CPV\":480,\"KHM\":497.46,\"CMR\":285.71,\"CAN\":184.99,\"CYM\":642.86,\"CAF\":0,\"TCD\":615.39,\"CHL\":265.52,\"CHN\":557.5,\"COL\":285.8,\"COM\":642.86,\"COG\":713.73,\"COD\":27.04,\"COK\":250,\"CRI\":63.01,\"CIV\":393.53,\"HRV\":174.48,\"CUB\":638.98,\"CYP\":512.24,\"CZE\":413.86,\"DNK\":143.3,\"DJI\":450,\"DMA\":600,\"DOM\":565.97,\"ECU\":209.7,\"EGY\":574.5,\"SLV\":99.29,\"GNQ\":605.1,\"ERI\":590.91,\"EST\":341.02,\"SWZ\":142.86,\"ETH\":23.55,\"EU\":213.02,\"EUROPE\":285,\"FLK\":1000,\"FRO\":354.17,\"FJI\":278.26,\"FIN\":72.25,\"FRA\":44.18,\"GUF\":204.08,\"PYF\":436.62,\"G20\":468.38,\"G7\":343.3,\"GAB\":429.47,\"GMB\":666.67,\"GEO\":143.06,\"DEU\":342.06,\"GHA\":452.86,\"GRC\":319.76,\"GRL\":111.11,\"GRD\":666.67,\"GLP\":493.9,\"GUM\":611.11,\"GTM\":272.66,\"GIN\":182.72,\"GNB\":625,\"GUY\":634.33,\"HTI\":534.65,\"HND\":289.5,\"HKG\":681.99,\"HUN\":182.82,\"ISL\":28.33,\"IND\":708.96,\"IDN\":682.43,\"IRN\":648.68,\"IRQ\":689.4,\"IRL\":279.79,\"ISR\":567.26,\"ITA\":287.75,\"JAM\":561.25,\"JPN\":483.73,\"JOR\":539.21,\"KAZ\":801.79,\"KEN\":84.83,\"KIR\":500,\"XKX\":958.72,\"KWT\":637.24,\"KGZ\":152.65,\"LAO\":232.12,\"LATIN AMERICA AND CARIBBEAN\":254.21,\"LVA\":136.22,\"LBN\":369.47,\"LSO\":20.83,\"LBR\":435.9,\"LBY\":830.53,\"LTU\":139.34,\"LUX\":134.62,\"MAC\":448.98,\"MDG\":477.27,\"MWI\":54.65,\"MYS\":604.43,\"MDV\":611.77,\"MLI\":394.5,\"MLT\":484.16,\"MTQ\":516.78,\"MRT\":481.71,\"MUS\":633.03,\"MEX\":483.14,\"MIDDLE EAST\":637.24,\"MDA\":629.56,\"MNG\":784.01,\"MNE\":413.51,\"MSR\":1000,\"MAR\":577.65,\"MOZ\":127.81,\"MMR\":569.69,\"NAM\":47.62,\"NRU\":750,\"NPL\":23.36,\"NLD\":252.7,\"NCL\":585.76,\"NZL\":120.11,\"NIC\":288.33,\"NER\":687.5,\"NGA\":507.85,\"NORTH AMERICA\":358.36,\"PRK\":344.26,\"MKD\":568.97,\"NOR\":30.75,\"OCEANIA\":495.47,\"OECD\":337.99,\"OMN\":545.33,\"PAK\":398.61,\"PSE\":460.78,\"PAN\":258.74,\"PNG\":513.74,\"PRY\":24.86,\"PER\":263.27,\"POL\":614.98,\"PRT\":111.8,\"PRI\":664.53,\"QAT\":602.83,\"REU\":525.22,\"ROU\":245.55,\"RUS\":446.17,\"RWA\":301.89,\"KNA\":636.36,\"LCA\":650,\"SPM\":600,\"VCT\":600,\"WSM\":400,\"STP\":555.56,\"SAU\":691.95,\"SEN\":535.4,\"SRB\":670.8,\"SYC\":571.43,\"SLE\":47.62,\"SGP\":498.74,\"SVK\":96.49,\"SVN\":227.11,\"SLB\":636.36,\"SOM\":523.81,\"ZAF\":713.9,\"KOR\":415.65,\"SSD\":610.17,\"ESP\":146.15,\"LKA\":509.78,\"SDN\":214.33,\"SUR\":383.18,\"SWE\":35.89,\"CHE\":36.72,\"SYR\":682.27,\"TWN\":635.15,\"TJK\":98.7,\"TZA\":371.59,\"THA\":555.43,\"PHL\":613.38,\"TGO\":478.26,\"TON\":571.43,\"TTO\":682.11,\"TUN\":560.25,\"TUR\":469.7,\"TKM\":1306.3,\"TCA\":653.85,\"UGA\":57.39,\"UKR\":250.47,\"ARE\":467.51,\"GBR\":215.79,\"USA\":383.55,\"URY\":96.7,\"UZB\":1121.18,\"VUT\":500,\"VEN\":180.25,\"VNM\":486.13,\"VGB\":647.06,\"VIR\":641.79,\"WORLD\":472.94,\"YEM\":586.32,\"ZMB\":111,\"ZWE\":298.44}; const type = \"average\"; export { data, type }; export default { data, type };"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/data.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var data_exports = {};
|
|
29
|
+
__export(data_exports, {
|
|
30
|
+
averageIntensity: () => import_average_intensities_min.default,
|
|
31
|
+
default: () => data_default,
|
|
32
|
+
marginalIntensity: () => import_marginal_intensities_2021_min.default
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(data_exports);
|
|
35
|
+
var import_average_intensities_min = __toESM(require("./data/average-intensities.min.js"));
|
|
36
|
+
var import_marginal_intensities_2021_min = __toESM(require("./data/marginal-intensities-2021.min.js"));
|
|
37
|
+
var data_default = { averageIntensity: import_average_intensities_min.default, marginalIntensity: import_marginal_intensities_2021_min.default };
|
|
38
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/data.js"],
|
|
4
|
+
"sourcesContent": ["import averageIntensity from \"./data/average-intensities.min.js\";\nimport marginalIntensity from \"./data/marginal-intensities-2021.min.js\";\n\nexport { averageIntensity, marginalIntensity };\nexport default { averageIntensity, marginalIntensity };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,yDAAAA;AAAA,EAAA;AAAA,gEAAAC;AAAA;AAAA;AAAA,qCAA6B;AAC7B,2CAA8B;AAG9B,IAAO,eAAQ,EAAE,iDAAAD,SAAkB,wDAAAC,QAAkB;",
|
|
6
|
+
"names": ["averageIntensity", "marginalIntensity"]
|
|
7
|
+
}
|
|
@@ -197,7 +197,7 @@ Falling back to default value.`
|
|
|
197
197
|
return adjustments;
|
|
198
198
|
}
|
|
199
199
|
function getApiRequestHeaders(comment = "") {
|
|
200
|
-
return { "User-Agent": `co2js/${"0.
|
|
200
|
+
return { "User-Agent": `co2js/${"0.17.0"} ${comment}` };
|
|
201
201
|
}
|
|
202
202
|
function outputRating(co2e, swdmVersion) {
|
|
203
203
|
let {
|
package/dist/cjs/hosting-node.js
CHANGED
|
@@ -27,6 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
var hosting_node_exports = {};
|
|
29
29
|
__export(hosting_node_exports, {
|
|
30
|
+
check: () => check,
|
|
30
31
|
default: () => hosting_node_default
|
|
31
32
|
});
|
|
32
33
|
module.exports = __toCommonJS(hosting_node_exports);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hosting-node.js"],
|
|
4
|
-
"sourcesContent": ["/*\n\nWe have a separate node-specific hosting.js file for node.\nThis uses the node-specific APIs for making http requests,\nand doing lookups against local JSON and sqlite databases.\nThis is used in the CommonJS build of co2.js\n\nThis lets us keep the total library small, and dependencies minimal.\n*/\n\nimport https from \"https\";\n\nimport hostingJSON from \"./hosting-json.js\";\nimport hostingJSONNode from \"./hosting-json.node.js\";\nimport { getApiRequestHeaders } from \"./helpers/index.js\";\n\n/**\n * Accept a url and perform an http request, returning the body\n * for parsing as JSON.\n *\n * @param {string} url\n * @param {string} userAgentIdentifier - Optional. The app, site, or organisation that is making the request.\n * @return {string}\n */\nasync function getBody(url, userAgentIdentifier) {\n return new Promise(function (resolve, reject) {\n // Do async job\n const req = https.get(\n url,\n { headers: getApiRequestHeaders(userAgentIdentifier) },\n function (res) {\n if (res.statusCode < 200 || res.statusCode >= 300) {\n return reject(\n new Error(\n `Could not get info from: ${url}. Status Code: ${res.statusCode}`\n )\n );\n }\n const data = [];\n\n res.on(\"data\", (chunk) => {\n data.push(chunk);\n });\n\n res.on(\"end\", () => resolve(Buffer.concat(data).toString()));\n }\n );\n req.end();\n });\n}\n\n/**\n * Check if a domain is hosted by a green web host.\n * @param {string|array} domain - The domain to check, or an array of domains to be checked.\n * @param {string[] | DomainCheckOptions} optionsOrDb - Optional. An object of domain check options, or a database list to use for lookups.\n * @param {string } userAgentIdentifier - Optional. The app, site, or organisation that is making the request.\n * @returns - A boolean if a string was provided, or an array of booleans if an array of domains was provided.\n * if a string was provided for `domain`: a boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n * if an array was provided for `domain`: an array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\n\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,mBAAkB;AAElB,0BAAwB;AACxB,+BAA4B;AAC5B,qBAAqC;AAUrC,eAAe,QAAQ,KAAK,qBAAqB;AAC/C,SAAO,IAAI,QAAQ,SAAU,SAAS,QAAQ;AAE5C,UAAM,MAAM,aAAAA,QAAM;AAAA,MAChB;AAAA,MACA,EAAE,aAAS,qCAAqB,mBAAmB,EAAE;AAAA,MACrD,SAAU,KAAK;AACb,YAAI,IAAI,aAAa,OAAO,IAAI,cAAc,KAAK;AACjD,iBAAO;AAAA,YACL,IAAI;AAAA,cACF,4BAA4B,GAAG,kBAAkB,IAAI,UAAU;AAAA,YACjE;AAAA,UACF;AAAA,QACF;AACA,cAAM,OAAO,CAAC;AAEd,YAAI,GAAG,QAAQ,CAAC,UAAU;AACxB,eAAK,KAAK,KAAK;AAAA,QACjB,CAAC;AAED,YAAI,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC;AAAA,MAC7D;AAAA,IACF;AACA,QAAI,IAAI;AAAA,EACV,CAAC;AACH;
|
|
4
|
+
"sourcesContent": ["/*\n\nWe have a separate node-specific hosting.js file for node.\nThis uses the node-specific APIs for making http requests,\nand doing lookups against local JSON and sqlite databases.\nThis is used in the CommonJS build of co2.js\n\nThis lets us keep the total library small, and dependencies minimal.\n*/\n\nimport https from \"https\";\n\nimport hostingJSON from \"./hosting-json.js\";\nimport hostingJSONNode from \"./hosting-json.node.js\";\nimport { getApiRequestHeaders } from \"./helpers/index.js\";\n\n/**\n * Accept a url and perform an http request, returning the body\n * for parsing as JSON.\n *\n * @param {string} url\n * @param {string} userAgentIdentifier - Optional. The app, site, or organisation that is making the request.\n * @return {string}\n */\nasync function getBody(url, userAgentIdentifier) {\n return new Promise(function (resolve, reject) {\n // Do async job\n const req = https.get(\n url,\n { headers: getApiRequestHeaders(userAgentIdentifier) },\n function (res) {\n if (res.statusCode < 200 || res.statusCode >= 300) {\n return reject(\n new Error(\n `Could not get info from: ${url}. Status Code: ${res.statusCode}`\n )\n );\n }\n const data = [];\n\n res.on(\"data\", (chunk) => {\n data.push(chunk);\n });\n\n res.on(\"end\", () => resolve(Buffer.concat(data).toString()));\n }\n );\n req.end();\n });\n}\n\n/**\n * Check if a domain is hosted by a green web host.\n * @param {string|array} domain - The domain to check, or an array of domains to be checked.\n * @param {string[] | DomainCheckOptions} optionsOrDb - Optional. An object of domain check options, or a database list to use for lookups.\n * @param {string } userAgentIdentifier - Optional. The app, site, or organisation that is making the request.\n * @returns - A boolean if a string was provided, or an array of booleans if an array of domains was provided.\n * if a string was provided for `domain`: a boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n * if an array was provided for `domain`: an array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\n\nexport function check(domain, optionsOrDb, userAgentIdentifier) {\n let db,\n options = {};\n if (!db && Array.isArray(optionsOrDb)) {\n db = optionsOrDb;\n } else {\n options = optionsOrDb;\n if (userAgentIdentifier) {\n options = { ...options, userAgentIdentifier };\n }\n db = optionsOrDb?.db;\n }\n\n if (db && options?.verbose) {\n throw new Error(\"verbose mode cannot be used with a local lookup database\");\n }\n if (db) {\n return hostingJSON.check(domain, db);\n }\n // is it a single domain or an array of them?\n if (typeof domain === \"string\") {\n return checkAgainstAPI(domain, options);\n } else {\n return checkDomainsAgainstAPI(domain, options);\n }\n}\n\n/**\n * Check if a domain is hosted by a green web host by querying the Green Web Foundation API.\n * @param {string} domain - The domain to check.\n * @param {DomainCheckOptions} options\n * @returns {boolean} - A boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n */\nasync function checkAgainstAPI(domain, options = {}) {\n const res = JSON.parse(\n await getBody(\n `https://api.thegreenwebfoundation.org/greencheck/${domain}`,\n options.userAgentIdentifier\n )\n );\n return options.verbose ? res : res.green;\n}\n\n/**\n * Check if an array of domains is hosted by a green web host by querying the Green Web Foundation API.\n * @param {array} domains - An array of domains to check.\n * @param {DomainCheckOptions} options\n * @returns {array} - An array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\nasync function checkDomainsAgainstAPI(domains, options = {}) {\n try {\n const allGreenCheckResults = JSON.parse(\n await getBody(\n `https://api.thegreenwebfoundation.org/v2/greencheckmulti/${JSON.stringify(\n domains\n )}`,\n options.userAgentIdentifier\n )\n );\n return options.verbose\n ? allGreenCheckResults\n : hostingJSON.greenDomainsFromResults(allGreenCheckResults);\n } catch (e) {\n return options.verbose ? {} : [];\n }\n}\n\nexport default {\n check,\n greendomains: hostingJSON.greenDomainsFromResults,\n loadJSON: hostingJSONNode.loadJSON,\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,mBAAkB;AAElB,0BAAwB;AACxB,+BAA4B;AAC5B,qBAAqC;AAUrC,eAAe,QAAQ,KAAK,qBAAqB;AAC/C,SAAO,IAAI,QAAQ,SAAU,SAAS,QAAQ;AAE5C,UAAM,MAAM,aAAAA,QAAM;AAAA,MAChB;AAAA,MACA,EAAE,aAAS,qCAAqB,mBAAmB,EAAE;AAAA,MACrD,SAAU,KAAK;AACb,YAAI,IAAI,aAAa,OAAO,IAAI,cAAc,KAAK;AACjD,iBAAO;AAAA,YACL,IAAI;AAAA,cACF,4BAA4B,GAAG,kBAAkB,IAAI,UAAU;AAAA,YACjE;AAAA,UACF;AAAA,QACF;AACA,cAAM,OAAO,CAAC;AAEd,YAAI,GAAG,QAAQ,CAAC,UAAU;AACxB,eAAK,KAAK,KAAK;AAAA,QACjB,CAAC;AAED,YAAI,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC;AAAA,MAC7D;AAAA,IACF;AACA,QAAI,IAAI;AAAA,EACV,CAAC;AACH;AAcO,SAAS,MAAM,QAAQ,aAAa,qBAAqB;AAC9D,MAAI,IACF,UAAU,CAAC;AACb,MAAI,CAAC,MAAM,MAAM,QAAQ,WAAW,GAAG;AACrC,SAAK;AAAA,EACP,OAAO;AACL,cAAU;AACV,QAAI,qBAAqB;AACvB,gBAAU,EAAE,GAAG,SAAS,oBAAoB;AAAA,IAC9C;AACA,SAAK,2CAAa;AAAA,EACpB;AAEA,MAAI,OAAM,mCAAS,UAAS;AAC1B,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,MAAI,IAAI;AACN,WAAO,oBAAAC,QAAY,MAAM,QAAQ,EAAE;AAAA,EACrC;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,gBAAgB,QAAQ,OAAO;AAAA,EACxC,OAAO;AACL,WAAO,uBAAuB,QAAQ,OAAO;AAAA,EAC/C;AACF;AASA,eAAe,gBAAgB,QAAQ,UAAU,CAAC,GAAG;AACnD,QAAM,MAAM,KAAK;AAAA,IACf,MAAM;AAAA,MACJ,oDAAoD,MAAM;AAAA,MAC1D,QAAQ;AAAA,IACV;AAAA,EACF;AACA,SAAO,QAAQ,UAAU,MAAM,IAAI;AACrC;AASA,eAAe,uBAAuB,SAAS,UAAU,CAAC,GAAG;AAC3D,MAAI;AACF,UAAM,uBAAuB,KAAK;AAAA,MAChC,MAAM;AAAA,QACJ,4DAA4D,KAAK;AAAA,UAC/D;AAAA,QACF,CAAC;AAAA,QACD,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO,QAAQ,UACX,uBACA,oBAAAA,QAAY,wBAAwB,oBAAoB;AAAA,EAC9D,SAAS,GAAG;AACV,WAAO,QAAQ,UAAU,CAAC,IAAI,CAAC;AAAA,EACjC;AACF;AAEA,IAAO,uBAAQ;AAAA,EACb;AAAA,EACA,cAAc,oBAAAA,QAAY;AAAA,EAC1B,UAAU,yBAAAC,QAAgB;AAC5B;",
|
|
6
6
|
"names": ["https", "hostingJSON", "hostingJSONNode"]
|
|
7
7
|
}
|
package/dist/cjs/hosting.js
CHANGED
|
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var hosting_exports = {};
|
|
30
30
|
__export(hosting_exports, {
|
|
31
|
+
check: () => check,
|
|
31
32
|
default: () => hosting_default
|
|
32
33
|
});
|
|
33
34
|
module.exports = __toCommonJS(hosting_exports);
|
package/dist/cjs/hosting.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hosting.js"],
|
|
4
|
-
"sourcesContent": ["\"use strict\";\n\nimport hostingAPI from \"./hosting-api.js\";\n\n/**\n * @module hosting\n */\n\n/**\n * Check if a domain is hosted by a green web host.\n * @param {string|array} domain - The domain to check, or an array of domains to be checked.\n * @param {string} optionsOrAgentId - Optional. An object of domain check options, or a string\n * representing the app, site, or organisation that is making the request.\n * @returns - A boolean if a string was provided, or an array of booleans if an array of domains was provided.\n * if a string was provided for `domain`: a boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n * if an array was provided for `domain`: an array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAuB;
|
|
4
|
+
"sourcesContent": ["\"use strict\";\n\nimport hostingAPI from \"./hosting-api.js\";\n\n/**\n * @module hosting\n */\n\n/**\n * Check if a domain is hosted by a green web host.\n * @param {string|array} domain - The domain to check, or an array of domains to be checked.\n * @param {string} optionsOrAgentId - Optional. An object of domain check options, or a string\n * representing the app, site, or organisation that is making the request.\n * @returns - A boolean if a string was provided, or an array of booleans if an array of domains was provided.\n * if a string was provided for `domain`: a boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n * if an array was provided for `domain`: an array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\n\nexport function check(domain, optionsOrAgentId) {\n return hostingAPI.check(domain, optionsOrAgentId);\n}\n\nexport default check;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAuB;AAkBhB,SAAS,MAAM,QAAQ,kBAAkB;AAC9C,SAAO,mBAAAA,QAAW,MAAM,QAAQ,gBAAgB;AAClD;AAEA,IAAO,kBAAQ;",
|
|
6
6
|
"names": ["hostingAPI"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var sustainable_web_design_exports = {};
|
|
20
|
+
__export(sustainable_web_design_exports, {
|
|
21
|
+
SustainableWebDesign: () => SustainableWebDesign,
|
|
22
|
+
default: () => sustainable_web_design_default
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(sustainable_web_design_exports);
|
|
25
|
+
var import_constants = require("./constants/index.js");
|
|
26
|
+
var import_helpers = require("./helpers/index.js");
|
|
27
|
+
class SustainableWebDesign {
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.options = options;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Accept a figure for bytes transferred and return an object representing
|
|
33
|
+
* the share of the total enrgy use of the entire system, broken down
|
|
34
|
+
* by each corresponding system component
|
|
35
|
+
*
|
|
36
|
+
* @param {number} bytes - the data transferred in bytes
|
|
37
|
+
* @return {object} Object containing the energy in kilowatt hours, keyed by system component
|
|
38
|
+
*/
|
|
39
|
+
energyPerByteByComponent(bytes) {
|
|
40
|
+
const transferedBytesToGb = bytes / import_constants.fileSize.GIGABYTE;
|
|
41
|
+
const energyUsage = transferedBytesToGb * import_constants.KWH_PER_GB;
|
|
42
|
+
return {
|
|
43
|
+
consumerDeviceEnergy: energyUsage * import_constants.END_USER_DEVICE_ENERGY,
|
|
44
|
+
networkEnergy: energyUsage * import_constants.NETWORK_ENERGY,
|
|
45
|
+
productionEnergy: energyUsage * import_constants.PRODUCTION_ENERGY,
|
|
46
|
+
dataCenterEnergy: energyUsage * import_constants.DATACENTER_ENERGY
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Accept an object keys by the different system components, and
|
|
51
|
+
* return an object with the co2 figures key by the each component
|
|
52
|
+
*
|
|
53
|
+
* @param {object} energyByComponent - energy grouped by the four system components
|
|
54
|
+
* @param {number} [carbonIntensity] - carbon intensity to apply to the datacentre values
|
|
55
|
+
* @return {number} the total number in grams of CO2 equivalent emissions
|
|
56
|
+
*/
|
|
57
|
+
co2byComponent(energyByComponent, carbonIntensity = import_constants.GLOBAL_GRID_INTENSITY, options = {}) {
|
|
58
|
+
let deviceCarbonIntensity = import_constants.GLOBAL_GRID_INTENSITY;
|
|
59
|
+
let networkCarbonIntensity = import_constants.GLOBAL_GRID_INTENSITY;
|
|
60
|
+
let dataCenterCarbonIntensity = import_constants.GLOBAL_GRID_INTENSITY;
|
|
61
|
+
let globalEmissions = import_constants.GLOBAL_GRID_INTENSITY;
|
|
62
|
+
if (options == null ? void 0 : options.gridIntensity) {
|
|
63
|
+
const { device, network, dataCenter } = options.gridIntensity;
|
|
64
|
+
if ((device == null ? void 0 : device.value) || (device == null ? void 0 : device.value) === 0) {
|
|
65
|
+
deviceCarbonIntensity = device.value;
|
|
66
|
+
}
|
|
67
|
+
if ((network == null ? void 0 : network.value) || (network == null ? void 0 : network.value) === 0) {
|
|
68
|
+
networkCarbonIntensity = network.value;
|
|
69
|
+
}
|
|
70
|
+
if ((dataCenter == null ? void 0 : dataCenter.value) || (dataCenter == null ? void 0 : dataCenter.value) === 0) {
|
|
71
|
+
dataCenterCarbonIntensity = dataCenter.value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (carbonIntensity === true) {
|
|
75
|
+
dataCenterCarbonIntensity = import_constants.RENEWABLES_GRID_INTENSITY;
|
|
76
|
+
}
|
|
77
|
+
const returnCO2ByComponent = {};
|
|
78
|
+
for (const [key, value] of Object.entries(energyByComponent)) {
|
|
79
|
+
if (key.startsWith("dataCenterEnergy")) {
|
|
80
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * dataCenterCarbonIntensity;
|
|
81
|
+
} else if (key.startsWith("consumerDeviceEnergy")) {
|
|
82
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * deviceCarbonIntensity;
|
|
83
|
+
} else if (key.startsWith("networkEnergy")) {
|
|
84
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * networkCarbonIntensity;
|
|
85
|
+
} else {
|
|
86
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * globalEmissions;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return returnCO2ByComponent;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Accept a figure for bytes transferred and return a single figure for CO2
|
|
93
|
+
* emissions. Where information exists about the origin data is being
|
|
94
|
+
* fetched from, a different carbon intensity figure
|
|
95
|
+
* is applied for the data centre share of the carbon intensity.
|
|
96
|
+
*
|
|
97
|
+
* @param {number} bytes - the data transferred in bytes
|
|
98
|
+
* @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not
|
|
99
|
+
* @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component
|
|
100
|
+
* @param {object} options - an object containing the grid intensity and first/return visitor values
|
|
101
|
+
* @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component
|
|
102
|
+
*/
|
|
103
|
+
perByte(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
|
|
104
|
+
if (bytes < 1) {
|
|
105
|
+
bytes = 0;
|
|
106
|
+
}
|
|
107
|
+
const energyBycomponent = this.energyPerByteByComponent(bytes, options);
|
|
108
|
+
if (typeof carbonIntensity !== "boolean") {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`perByte expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const co2ValuesbyComponent = this.co2byComponent(
|
|
114
|
+
energyBycomponent,
|
|
115
|
+
carbonIntensity,
|
|
116
|
+
options
|
|
117
|
+
);
|
|
118
|
+
const co2Values = Object.values(co2ValuesbyComponent);
|
|
119
|
+
const co2ValuesSum = co2Values.reduce(
|
|
120
|
+
(prevValue, currentValue) => prevValue + currentValue
|
|
121
|
+
);
|
|
122
|
+
if (segmentResults) {
|
|
123
|
+
return { ...co2ValuesbyComponent, total: co2ValuesSum };
|
|
124
|
+
}
|
|
125
|
+
return co2ValuesSum;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Accept a figure for bytes transferred and return a single figure for CO2
|
|
129
|
+
* emissions. This method applies caching assumptions from the original Sustainable Web Design model.
|
|
130
|
+
*
|
|
131
|
+
* @param {number} bytes - the data transferred in bytes
|
|
132
|
+
* @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not
|
|
133
|
+
* @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component
|
|
134
|
+
* @param {object} options - an object containing the grid intensity and first/return visitor values
|
|
135
|
+
* @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component
|
|
136
|
+
*/
|
|
137
|
+
perVisit(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
|
|
138
|
+
const energyBycomponent = this.energyPerVisitByComponent(bytes, options);
|
|
139
|
+
if (typeof carbonIntensity !== "boolean") {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
const co2ValuesbyComponent = this.co2byComponent(
|
|
145
|
+
energyBycomponent,
|
|
146
|
+
carbonIntensity,
|
|
147
|
+
options
|
|
148
|
+
);
|
|
149
|
+
const co2Values = Object.values(co2ValuesbyComponent);
|
|
150
|
+
const co2ValuesSum = co2Values.reduce(
|
|
151
|
+
(prevValue, currentValue) => prevValue + currentValue
|
|
152
|
+
);
|
|
153
|
+
if (segmentResults) {
|
|
154
|
+
return { ...co2ValuesbyComponent, total: co2ValuesSum };
|
|
155
|
+
}
|
|
156
|
+
return co2ValuesSum;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Accept a figure for bytes transferred and return the number of kilowatt hours used
|
|
160
|
+
* by the total system for this data transfer
|
|
161
|
+
*
|
|
162
|
+
* @param {number} bytes
|
|
163
|
+
* @return {number} the number of kilowatt hours used
|
|
164
|
+
*/
|
|
165
|
+
energyPerByte(bytes) {
|
|
166
|
+
const energyByComponent = this.energyPerByteByComponent(bytes);
|
|
167
|
+
const energyValues = Object.values(energyByComponent);
|
|
168
|
+
return energyValues.reduce(
|
|
169
|
+
(prevValue, currentValue) => prevValue + currentValue
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Accept a figure for bytes transferred, and return an object containing figures
|
|
174
|
+
* per system component, with the caching assumptions applied. This tries to account
|
|
175
|
+
* for webpages being loaded from a cache by browsers, so if you had a thousand page views,
|
|
176
|
+
* and tried to work out the energy per visit, the numbers would reflect the reduced amounts
|
|
177
|
+
* of transfer.
|
|
178
|
+
*
|
|
179
|
+
* @param {number} bytes - the data transferred in bytes for loading a webpage
|
|
180
|
+
* @param {number} firstView - what percentage of visits are loading this page for the first time
|
|
181
|
+
* @param {number} returnView - what percentage of visits are loading this page for subsequent times
|
|
182
|
+
* @param {number} dataReloadRatio - what percentage of a page is reloaded on each subsequent page view
|
|
183
|
+
*
|
|
184
|
+
* @return {object} Object containing the energy in kilowatt hours, keyed by system component
|
|
185
|
+
*/
|
|
186
|
+
energyPerVisitByComponent(bytes, options = {}, firstView = import_constants.FIRST_TIME_VIEWING_PERCENTAGE, returnView = import_constants.RETURNING_VISITOR_PERCENTAGE, dataReloadRatio = import_constants.PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD) {
|
|
187
|
+
if (options.dataReloadRatio || options.dataReloadRatio === 0) {
|
|
188
|
+
dataReloadRatio = options.dataReloadRatio;
|
|
189
|
+
}
|
|
190
|
+
if (options.firstVisitPercentage || options.firstVisitPercentage === 0) {
|
|
191
|
+
firstView = options.firstVisitPercentage;
|
|
192
|
+
}
|
|
193
|
+
if (options.returnVisitPercentage || options.returnVisitPercentage === 0) {
|
|
194
|
+
returnView = options.returnVisitPercentage;
|
|
195
|
+
}
|
|
196
|
+
const energyBycomponent = this.energyPerByteByComponent(bytes);
|
|
197
|
+
const cacheAdjustedSegmentEnergy = {};
|
|
198
|
+
const energyValues = Object.values(energyBycomponent);
|
|
199
|
+
for (const [key, value] of Object.entries(energyBycomponent)) {
|
|
200
|
+
cacheAdjustedSegmentEnergy[`${key} - first`] = value * firstView;
|
|
201
|
+
cacheAdjustedSegmentEnergy[`${key} - subsequent`] = value * returnView * dataReloadRatio;
|
|
202
|
+
}
|
|
203
|
+
return cacheAdjustedSegmentEnergy;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Accept a figure for bytes, and return the total figure for energy per visit
|
|
207
|
+
* using the default caching assumptions for loading a single website
|
|
208
|
+
*
|
|
209
|
+
* @param {number} bytes
|
|
210
|
+
* @return {number} the total energy use for the visit, after applying the caching assumptions
|
|
211
|
+
*/
|
|
212
|
+
energyPerVisit(bytes) {
|
|
213
|
+
let firstVisits = 0;
|
|
214
|
+
let subsequentVisits = 0;
|
|
215
|
+
const energyBycomponent = Object.entries(
|
|
216
|
+
this.energyPerVisitByComponent(bytes)
|
|
217
|
+
);
|
|
218
|
+
for (const [key, val] of energyBycomponent) {
|
|
219
|
+
if (key.indexOf("first") > 0) {
|
|
220
|
+
firstVisits += val;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
for (const [key, val] of energyBycomponent) {
|
|
224
|
+
if (key.indexOf("subsequent") > 0) {
|
|
225
|
+
subsequentVisits += val;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return firstVisits + subsequentVisits;
|
|
229
|
+
}
|
|
230
|
+
emissionsPerVisitInGrams(energyPerVisit, carbonintensity = import_constants.GLOBAL_GRID_INTENSITY) {
|
|
231
|
+
return (0, import_helpers.formatNumber)(energyPerVisit * carbonintensity);
|
|
232
|
+
}
|
|
233
|
+
annualEnergyInKwh(energyPerVisit, monthlyVisitors = 1e3) {
|
|
234
|
+
return energyPerVisit * monthlyVisitors * 12;
|
|
235
|
+
}
|
|
236
|
+
annualEmissionsInGrams(co2grams, monthlyVisitors = 1e3) {
|
|
237
|
+
return co2grams * monthlyVisitors * 12;
|
|
238
|
+
}
|
|
239
|
+
annualSegmentEnergy(annualEnergy) {
|
|
240
|
+
return {
|
|
241
|
+
consumerDeviceEnergy: (0, import_helpers.formatNumber)(annualEnergy * import_constants.END_USER_DEVICE_ENERGY),
|
|
242
|
+
networkEnergy: (0, import_helpers.formatNumber)(annualEnergy * import_constants.NETWORK_ENERGY),
|
|
243
|
+
dataCenterEnergy: (0, import_helpers.formatNumber)(annualEnergy * import_constants.DATACENTER_ENERGY),
|
|
244
|
+
productionEnergy: (0, import_helpers.formatNumber)(annualEnergy * import_constants.PRODUCTION_ENERGY)
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
var sustainable_web_design_default = SustainableWebDesign;
|
|
249
|
+
//# sourceMappingURL=sustainable-web-design.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sustainable-web-design.js"],
|
|
4
|
+
"sourcesContent": ["\"use strict\";\n\n/**\n * Sustainable Web Design\n *\n * Updated calculations and figures from\n * https://sustainablewebdesign.org/calculating-digital-emissions/\n *\n */\n\nimport {\n fileSize,\n KWH_PER_GB,\n END_USER_DEVICE_ENERGY,\n NETWORK_ENERGY,\n DATACENTER_ENERGY,\n PRODUCTION_ENERGY,\n GLOBAL_GRID_INTENSITY,\n RENEWABLES_GRID_INTENSITY,\n FIRST_TIME_VIEWING_PERCENTAGE,\n RETURNING_VISITOR_PERCENTAGE,\n PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,\n} from \"./constants/index.js\";\nimport { formatNumber } from \"./helpers/index.js\";\n\nclass SustainableWebDesign {\n constructor(options) {\n this.options = options;\n }\n\n /**\n * Accept a figure for bytes transferred and return an object representing\n * the share of the total enrgy use of the entire system, broken down\n * by each corresponding system component\n *\n * @param {number} bytes - the data transferred in bytes\n * @return {object} Object containing the energy in kilowatt hours, keyed by system component\n */\n energyPerByteByComponent(bytes) {\n const transferedBytesToGb = bytes / fileSize.GIGABYTE;\n const energyUsage = transferedBytesToGb * KWH_PER_GB;\n\n // return the total energy, with breakdown by component\n return {\n consumerDeviceEnergy: energyUsage * END_USER_DEVICE_ENERGY,\n networkEnergy: energyUsage * NETWORK_ENERGY,\n productionEnergy: energyUsage * PRODUCTION_ENERGY,\n dataCenterEnergy: energyUsage * DATACENTER_ENERGY,\n };\n }\n /**\n * Accept an object keys by the different system components, and\n * return an object with the co2 figures key by the each component\n *\n * @param {object} energyByComponent - energy grouped by the four system components\n * @param {number} [carbonIntensity] - carbon intensity to apply to the datacentre values\n * @return {number} the total number in grams of CO2 equivalent emissions\n */\n co2byComponent(\n energyByComponent,\n carbonIntensity = GLOBAL_GRID_INTENSITY,\n options = {}\n ) {\n let deviceCarbonIntensity = GLOBAL_GRID_INTENSITY;\n let networkCarbonIntensity = GLOBAL_GRID_INTENSITY;\n let dataCenterCarbonIntensity = GLOBAL_GRID_INTENSITY;\n\n let globalEmissions = GLOBAL_GRID_INTENSITY;\n\n if (options?.gridIntensity) {\n const { device, network, dataCenter } = options.gridIntensity;\n\n if (device?.value || device?.value === 0) {\n deviceCarbonIntensity = device.value;\n }\n if (network?.value || network?.value === 0) {\n networkCarbonIntensity = network.value;\n }\n // If the user has set a carbon intensity value for the datacentre, then that overrides everything and is used\n if (dataCenter?.value || dataCenter?.value === 0) {\n dataCenterCarbonIntensity = dataCenter.value;\n }\n }\n\n // If the user passes in a TRUE value (green web host), then use the renewables intensity value\n if (carbonIntensity === true) {\n dataCenterCarbonIntensity = RENEWABLES_GRID_INTENSITY;\n }\n\n const returnCO2ByComponent = {};\n for (const [key, value] of Object.entries(energyByComponent)) {\n // we update the datacentre, as that's what we have information\n // about.\n if (key.startsWith(\"dataCenterEnergy\")) {\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * dataCenterCarbonIntensity;\n } else if (key.startsWith(\"consumerDeviceEnergy\")) {\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * deviceCarbonIntensity;\n } else if (key.startsWith(\"networkEnergy\")) {\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * networkCarbonIntensity;\n } else {\n // Use the global intensity for the remaining segments\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * globalEmissions;\n }\n }\n\n return returnCO2ByComponent;\n }\n\n /**\n * Accept a figure for bytes transferred and return a single figure for CO2\n * emissions. Where information exists about the origin data is being\n * fetched from, a different carbon intensity figure\n * is applied for the data centre share of the carbon intensity.\n *\n * @param {number} bytes - the data transferred in bytes\n * @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not\n * @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component\n * @param {object} options - an object containing the grid intensity and first/return visitor values\n * @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component\n */\n perByte(\n bytes,\n carbonIntensity = false,\n segmentResults = false,\n options = {}\n ) {\n if (bytes < 1) {\n bytes = 0;\n }\n\n const energyBycomponent = this.energyPerByteByComponent(bytes, options);\n\n // otherwise when faced with non numeric values throw an error\n if (typeof carbonIntensity !== \"boolean\") {\n throw new Error(\n `perByte expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`\n );\n }\n\n const co2ValuesbyComponent = this.co2byComponent(\n energyBycomponent,\n carbonIntensity,\n options\n );\n\n // pull out our values\u2026\n const co2Values = Object.values(co2ValuesbyComponent);\n const co2ValuesSum = co2Values.reduce(\n (prevValue, currentValue) => prevValue + currentValue\n );\n\n if (segmentResults) {\n return { ...co2ValuesbyComponent, total: co2ValuesSum };\n }\n\n return co2ValuesSum;\n }\n\n /**\n * Accept a figure for bytes transferred and return a single figure for CO2\n * emissions. This method applies caching assumptions from the original Sustainable Web Design model.\n *\n * @param {number} bytes - the data transferred in bytes\n * @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not\n * @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component\n * @param {object} options - an object containing the grid intensity and first/return visitor values\n * @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component\n */\n perVisit(\n bytes,\n carbonIntensity = false,\n segmentResults = false,\n options = {}\n ) {\n const energyBycomponent = this.energyPerVisitByComponent(bytes, options);\n\n if (typeof carbonIntensity !== \"boolean\") {\n // otherwise when faced with non numeric values throw an error\n throw new Error(\n `perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`\n );\n }\n\n const co2ValuesbyComponent = this.co2byComponent(\n energyBycomponent,\n carbonIntensity,\n options\n );\n\n // pull out our values\u2026\n const co2Values = Object.values(co2ValuesbyComponent);\n const co2ValuesSum = co2Values.reduce(\n (prevValue, currentValue) => prevValue + currentValue\n );\n\n if (segmentResults) {\n return { ...co2ValuesbyComponent, total: co2ValuesSum };\n }\n\n // so we can return their sum\n return co2ValuesSum;\n }\n\n /**\n * Accept a figure for bytes transferred and return the number of kilowatt hours used\n * by the total system for this data transfer\n *\n * @param {number} bytes\n * @return {number} the number of kilowatt hours used\n */\n energyPerByte(bytes) {\n const energyByComponent = this.energyPerByteByComponent(bytes);\n\n // pull out our values\u2026\n const energyValues = Object.values(energyByComponent);\n\n // so we can return their sum\n return energyValues.reduce(\n (prevValue, currentValue) => prevValue + currentValue\n );\n }\n\n /**\n * Accept a figure for bytes transferred, and return an object containing figures\n * per system component, with the caching assumptions applied. This tries to account\n * for webpages being loaded from a cache by browsers, so if you had a thousand page views,\n * and tried to work out the energy per visit, the numbers would reflect the reduced amounts\n * of transfer.\n *\n * @param {number} bytes - the data transferred in bytes for loading a webpage\n * @param {number} firstView - what percentage of visits are loading this page for the first time\n * @param {number} returnView - what percentage of visits are loading this page for subsequent times\n * @param {number} dataReloadRatio - what percentage of a page is reloaded on each subsequent page view\n *\n * @return {object} Object containing the energy in kilowatt hours, keyed by system component\n */\n energyPerVisitByComponent(\n bytes,\n options = {},\n firstView = FIRST_TIME_VIEWING_PERCENTAGE,\n returnView = RETURNING_VISITOR_PERCENTAGE,\n dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD\n ) {\n if (options.dataReloadRatio || options.dataReloadRatio === 0) {\n dataReloadRatio = options.dataReloadRatio;\n }\n\n if (options.firstVisitPercentage || options.firstVisitPercentage === 0) {\n firstView = options.firstVisitPercentage;\n }\n\n if (options.returnVisitPercentage || options.returnVisitPercentage === 0) {\n returnView = options.returnVisitPercentage;\n }\n\n const energyBycomponent = this.energyPerByteByComponent(bytes);\n const cacheAdjustedSegmentEnergy = {};\n\n const energyValues = Object.values(energyBycomponent);\n\n // for this, we want\n for (const [key, value] of Object.entries(energyBycomponent)) {\n // represent the first load\n cacheAdjustedSegmentEnergy[`${key} - first`] = value * firstView;\n\n // then represent the subsequent load\n cacheAdjustedSegmentEnergy[`${key} - subsequent`] =\n value * returnView * dataReloadRatio;\n }\n\n return cacheAdjustedSegmentEnergy;\n }\n\n /**\n * Accept a figure for bytes, and return the total figure for energy per visit\n * using the default caching assumptions for loading a single website\n *\n * @param {number} bytes\n * @return {number} the total energy use for the visit, after applying the caching assumptions\n */\n energyPerVisit(bytes) {\n // fetch the values using the default caching assumptions\n // const energyValues = Object.values(this.energyPerVisitByComponent(bytes));\n\n let firstVisits = 0;\n let subsequentVisits = 0;\n\n const energyBycomponent = Object.entries(\n this.energyPerVisitByComponent(bytes)\n );\n\n for (const [key, val] of energyBycomponent) {\n if (key.indexOf(\"first\") > 0) {\n firstVisits += val;\n }\n }\n\n for (const [key, val] of energyBycomponent) {\n if (key.indexOf(\"subsequent\") > 0) {\n subsequentVisits += val;\n }\n }\n\n return firstVisits + subsequentVisits;\n }\n\n emissionsPerVisitInGrams(\n energyPerVisit,\n carbonintensity = GLOBAL_GRID_INTENSITY\n ) {\n return formatNumber(energyPerVisit * carbonintensity);\n }\n\n annualEnergyInKwh(energyPerVisit, monthlyVisitors = 1000) {\n return energyPerVisit * monthlyVisitors * 12;\n }\n\n annualEmissionsInGrams(co2grams, monthlyVisitors = 1000) {\n return co2grams * monthlyVisitors * 12;\n }\n\n annualSegmentEnergy(annualEnergy) {\n return {\n consumerDeviceEnergy: formatNumber(annualEnergy * END_USER_DEVICE_ENERGY),\n networkEnergy: formatNumber(annualEnergy * NETWORK_ENERGY),\n dataCenterEnergy: formatNumber(annualEnergy * DATACENTER_ENERGY),\n productionEnergy: formatNumber(annualEnergy * PRODUCTION_ENERGY),\n };\n }\n}\n\nexport { SustainableWebDesign };\nexport default SustainableWebDesign;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/esm/co2.js
CHANGED
|
@@ -43,6 +43,8 @@ class CO2 {
|
|
|
43
43
|
if ((options == null ? void 0 : options.version) === 4) {
|
|
44
44
|
this.model = new SustainableWebDesignV4();
|
|
45
45
|
}
|
|
46
|
+
} else if (!(options == null ? void 0 : options.model)) {
|
|
47
|
+
console.warn("------\nWARNING: We are changing the default estimation model in CO2.js to Sustainable Web Design v4 in the next version (v0.18) of CO2.js. This change will take place in February 2026.\n\nIf you would like to keep using Sustainable Web Design v3, please make sure to explicitly set it in your code. See https://developers.thegreenwebfoundation.org/co2js/models/#using-sustainable-web-design-model-version-3 for details.\n------\n ");
|
|
46
48
|
} else if (options == null ? void 0 : options.model) {
|
|
47
49
|
throw new Error(
|
|
48
50
|
'"'.concat(options.model, '" is not a valid model. Please use "1byte" for the OneByte model, and "swd" for the Sustainable Web Design model.\nSee https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const data = { "AFG": 123.71, "AFRICA":
|
|
1
|
+
const data = { "AFG": 123.71, "AFRICA": 545.09, "ALB": 24.42, "DZA": 633.65, "ASM": 647.06, "AGO": 167.22, "ATG": 611.11, "ARG": 344.83, "ARM": 243.52, "ABW": 550, "ASEAN": 573.65, "ASIA": 572.12, "AUS": 553.76, "AUT": 102.62, "AZE": 632.89, "BHS": 653.66, "BHR": 902.41, "BGD": 694.63, "BRB": 600, "BLR": 323.63, "BEL": 117.58, "BLZ": 155.56, "BEN": 590, "BTN": 24.19, "BOL": 468.02, "BIH": 638.05, "BWA": 849.42, "BRA": 106.06, "BRN": 892.67, "BGR": 264.21, "BFA": 554.91, "BDI": 230.77, "CPV": 480, "KHM": 497.46, "CMR": 285.71, "CAN": 184.99, "CYM": 642.86, "CAF": 0, "TCD": 615.39, "CHL": 265.52, "CHN": 557.5, "COL": 285.8, "COM": 642.86, "COG": 713.73, "COD": 27.04, "COK": 250, "CRI": 63.01, "CIV": 393.53, "HRV": 174.48, "CUB": 638.98, "CYP": 512.24, "CZE": 413.86, "DNK": 143.3, "DJI": 450, "DMA": 600, "DOM": 565.97, "ECU": 209.7, "EGY": 574.5, "SLV": 99.29, "GNQ": 605.1, "ERI": 590.91, "EST": 341.02, "SWZ": 142.86, "ETH": 23.55, "EU": 213.02, "EUROPE": 285, "FLK": 1e3, "FRO": 354.17, "FJI": 278.26, "FIN": 72.25, "FRA": 44.18, "GUF": 204.08, "PYF": 436.62, "G20": 468.38, "G7": 343.3, "GAB": 429.47, "GMB": 666.67, "GEO": 143.06, "DEU": 342.06, "GHA": 452.86, "GRC": 319.76, "GRL": 111.11, "GRD": 666.67, "GLP": 493.9, "GUM": 611.11, "GTM": 272.66, "GIN": 182.72, "GNB": 625, "GUY": 634.33, "HTI": 534.65, "HND": 289.5, "HKG": 681.99, "HUN": 182.82, "ISL": 28.33, "IND": 708.96, "IDN": 682.43, "IRN": 648.68, "IRQ": 689.4, "IRL": 279.79, "ISR": 567.26, "ITA": 287.75, "JAM": 561.25, "JPN": 483.73, "JOR": 539.21, "KAZ": 801.79, "KEN": 84.83, "KIR": 500, "XKX": 958.72, "KWT": 637.24, "KGZ": 152.65, "LAO": 232.12, "LATIN AMERICA AND CARIBBEAN": 254.21, "LVA": 136.22, "LBN": 369.47, "LSO": 20.83, "LBR": 435.9, "LBY": 830.53, "LTU": 139.34, "LUX": 134.62, "MAC": 448.98, "MDG": 477.27, "MWI": 54.65, "MYS": 604.43, "MDV": 611.77, "MLI": 394.5, "MLT": 484.16, "MTQ": 516.78, "MRT": 481.71, "MUS": 633.03, "MEX": 483.14, "MIDDLE EAST": 637.24, "MDA": 629.56, "MNG": 784.01, "MNE": 413.51, "MSR": 1e3, "MAR": 577.65, "MOZ": 127.81, "MMR": 569.69, "NAM": 47.62, "NRU": 750, "NPL": 23.36, "NLD": 252.7, "NCL": 585.76, "NZL": 120.11, "NIC": 288.33, "NER": 687.5, "NGA": 507.85, "NORTH AMERICA": 358.36, "PRK": 344.26, "MKD": 568.97, "NOR": 30.75, "OCEANIA": 495.47, "OECD": 337.99, "OMN": 545.33, "PAK": 398.61, "PSE": 460.78, "PAN": 258.74, "PNG": 513.74, "PRY": 24.86, "PER": 263.27, "POL": 614.98, "PRT": 111.8, "PRI": 664.53, "QAT": 602.83, "REU": 525.22, "ROU": 245.55, "RUS": 446.17, "RWA": 301.89, "KNA": 636.36, "LCA": 650, "SPM": 600, "VCT": 600, "WSM": 400, "STP": 555.56, "SAU": 691.95, "SEN": 535.4, "SRB": 670.8, "SYC": 571.43, "SLE": 47.62, "SGP": 498.74, "SVK": 96.49, "SVN": 227.11, "SLB": 636.36, "SOM": 523.81, "ZAF": 713.9, "KOR": 415.65, "SSD": 610.17, "ESP": 146.15, "LKA": 509.78, "SDN": 214.33, "SUR": 383.18, "SWE": 35.89, "CHE": 36.72, "SYR": 682.27, "TWN": 635.15, "TJK": 98.7, "TZA": 371.59, "THA": 555.43, "PHL": 613.38, "TGO": 478.26, "TON": 571.43, "TTO": 682.11, "TUN": 560.25, "TUR": 469.7, "TKM": 1306.3, "TCA": 653.85, "UGA": 57.39, "UKR": 250.47, "ARE": 467.51, "GBR": 215.79, "USA": 383.55, "URY": 96.7, "UZB": 1121.18, "VUT": 500, "VEN": 180.25, "VNM": 486.13, "VGB": 647.06, "VIR": 641.79, "WORLD": 472.94, "YEM": 586.32, "ZMB": 111, "ZWE": 298.44 };
|
|
2
2
|
const type = "average";
|
|
3
3
|
var average_intensities_min_default = { data, type };
|
|
4
4
|
export {
|
package/dist/esm/data.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import averageIntensity from "./data/average-intensities.min.js";
|
|
2
|
+
import marginalIntensity from "./data/marginal-intensities-2021.min.js";
|
|
3
|
+
var data_default = { averageIntensity, marginalIntensity };
|
|
4
|
+
export {
|
|
5
|
+
averageIntensity,
|
|
6
|
+
data_default as default,
|
|
7
|
+
marginalIntensity
|
|
8
|
+
};
|
|
@@ -164,7 +164,7 @@ function parseVisitTraceOptions(options = {}, version = 3, green = false) {
|
|
|
164
164
|
return adjustments;
|
|
165
165
|
}
|
|
166
166
|
function getApiRequestHeaders(comment = "") {
|
|
167
|
-
return { "User-Agent": "co2js/".concat("0.
|
|
167
|
+
return { "User-Agent": "co2js/".concat("0.17.0", " ").concat(comment) };
|
|
168
168
|
}
|
|
169
169
|
function outputRating(co2e, swdmVersion) {
|
|
170
170
|
let {
|
package/dist/esm/hosting.js
CHANGED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
import {
|
|
21
|
+
fileSize,
|
|
22
|
+
KWH_PER_GB,
|
|
23
|
+
END_USER_DEVICE_ENERGY,
|
|
24
|
+
NETWORK_ENERGY,
|
|
25
|
+
DATACENTER_ENERGY,
|
|
26
|
+
PRODUCTION_ENERGY,
|
|
27
|
+
GLOBAL_GRID_INTENSITY,
|
|
28
|
+
RENEWABLES_GRID_INTENSITY,
|
|
29
|
+
FIRST_TIME_VIEWING_PERCENTAGE,
|
|
30
|
+
RETURNING_VISITOR_PERCENTAGE,
|
|
31
|
+
PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD
|
|
32
|
+
} from "./constants/index.js";
|
|
33
|
+
import { formatNumber } from "./helpers/index.js";
|
|
34
|
+
class SustainableWebDesign {
|
|
35
|
+
constructor(options) {
|
|
36
|
+
this.options = options;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Accept a figure for bytes transferred and return an object representing
|
|
40
|
+
* the share of the total enrgy use of the entire system, broken down
|
|
41
|
+
* by each corresponding system component
|
|
42
|
+
*
|
|
43
|
+
* @param {number} bytes - the data transferred in bytes
|
|
44
|
+
* @return {object} Object containing the energy in kilowatt hours, keyed by system component
|
|
45
|
+
*/
|
|
46
|
+
energyPerByteByComponent(bytes) {
|
|
47
|
+
const transferedBytesToGb = bytes / fileSize.GIGABYTE;
|
|
48
|
+
const energyUsage = transferedBytesToGb * KWH_PER_GB;
|
|
49
|
+
return {
|
|
50
|
+
consumerDeviceEnergy: energyUsage * END_USER_DEVICE_ENERGY,
|
|
51
|
+
networkEnergy: energyUsage * NETWORK_ENERGY,
|
|
52
|
+
productionEnergy: energyUsage * PRODUCTION_ENERGY,
|
|
53
|
+
dataCenterEnergy: energyUsage * DATACENTER_ENERGY
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Accept an object keys by the different system components, and
|
|
58
|
+
* return an object with the co2 figures key by the each component
|
|
59
|
+
*
|
|
60
|
+
* @param {object} energyByComponent - energy grouped by the four system components
|
|
61
|
+
* @param {number} [carbonIntensity] - carbon intensity to apply to the datacentre values
|
|
62
|
+
* @return {number} the total number in grams of CO2 equivalent emissions
|
|
63
|
+
*/
|
|
64
|
+
co2byComponent(energyByComponent, carbonIntensity = GLOBAL_GRID_INTENSITY, options = {}) {
|
|
65
|
+
let deviceCarbonIntensity = GLOBAL_GRID_INTENSITY;
|
|
66
|
+
let networkCarbonIntensity = GLOBAL_GRID_INTENSITY;
|
|
67
|
+
let dataCenterCarbonIntensity = GLOBAL_GRID_INTENSITY;
|
|
68
|
+
let globalEmissions = GLOBAL_GRID_INTENSITY;
|
|
69
|
+
if (options == null ? void 0 : options.gridIntensity) {
|
|
70
|
+
const { device, network, dataCenter } = options.gridIntensity;
|
|
71
|
+
if ((device == null ? void 0 : device.value) || (device == null ? void 0 : device.value) === 0) {
|
|
72
|
+
deviceCarbonIntensity = device.value;
|
|
73
|
+
}
|
|
74
|
+
if ((network == null ? void 0 : network.value) || (network == null ? void 0 : network.value) === 0) {
|
|
75
|
+
networkCarbonIntensity = network.value;
|
|
76
|
+
}
|
|
77
|
+
if ((dataCenter == null ? void 0 : dataCenter.value) || (dataCenter == null ? void 0 : dataCenter.value) === 0) {
|
|
78
|
+
dataCenterCarbonIntensity = dataCenter.value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (carbonIntensity === true) {
|
|
82
|
+
dataCenterCarbonIntensity = RENEWABLES_GRID_INTENSITY;
|
|
83
|
+
}
|
|
84
|
+
const returnCO2ByComponent = {};
|
|
85
|
+
for (const [key, value] of Object.entries(energyByComponent)) {
|
|
86
|
+
if (key.startsWith("dataCenterEnergy")) {
|
|
87
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * dataCenterCarbonIntensity;
|
|
88
|
+
} else if (key.startsWith("consumerDeviceEnergy")) {
|
|
89
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * deviceCarbonIntensity;
|
|
90
|
+
} else if (key.startsWith("networkEnergy")) {
|
|
91
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * networkCarbonIntensity;
|
|
92
|
+
} else {
|
|
93
|
+
returnCO2ByComponent[key.replace("Energy", "CO2")] = value * globalEmissions;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return returnCO2ByComponent;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Accept a figure for bytes transferred and return a single figure for CO2
|
|
100
|
+
* emissions. Where information exists about the origin data is being
|
|
101
|
+
* fetched from, a different carbon intensity figure
|
|
102
|
+
* is applied for the data centre share of the carbon intensity.
|
|
103
|
+
*
|
|
104
|
+
* @param {number} bytes - the data transferred in bytes
|
|
105
|
+
* @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not
|
|
106
|
+
* @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component
|
|
107
|
+
* @param {object} options - an object containing the grid intensity and first/return visitor values
|
|
108
|
+
* @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component
|
|
109
|
+
*/
|
|
110
|
+
perByte(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
|
|
111
|
+
if (bytes < 1) {
|
|
112
|
+
bytes = 0;
|
|
113
|
+
}
|
|
114
|
+
const energyBycomponent = this.energyPerByteByComponent(bytes, options);
|
|
115
|
+
if (typeof carbonIntensity !== "boolean") {
|
|
116
|
+
throw new Error(
|
|
117
|
+
"perByte expects a boolean for the carbon intensity value. Received: ".concat(carbonIntensity)
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
const co2ValuesbyComponent = this.co2byComponent(
|
|
121
|
+
energyBycomponent,
|
|
122
|
+
carbonIntensity,
|
|
123
|
+
options
|
|
124
|
+
);
|
|
125
|
+
const co2Values = Object.values(co2ValuesbyComponent);
|
|
126
|
+
const co2ValuesSum = co2Values.reduce(
|
|
127
|
+
(prevValue, currentValue) => prevValue + currentValue
|
|
128
|
+
);
|
|
129
|
+
if (segmentResults) {
|
|
130
|
+
return __spreadProps(__spreadValues({}, co2ValuesbyComponent), { total: co2ValuesSum });
|
|
131
|
+
}
|
|
132
|
+
return co2ValuesSum;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Accept a figure for bytes transferred and return a single figure for CO2
|
|
136
|
+
* emissions. This method applies caching assumptions from the original Sustainable Web Design model.
|
|
137
|
+
*
|
|
138
|
+
* @param {number} bytes - the data transferred in bytes
|
|
139
|
+
* @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not
|
|
140
|
+
* @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component
|
|
141
|
+
* @param {object} options - an object containing the grid intensity and first/return visitor values
|
|
142
|
+
* @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component
|
|
143
|
+
*/
|
|
144
|
+
perVisit(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
|
|
145
|
+
const energyBycomponent = this.energyPerVisitByComponent(bytes, options);
|
|
146
|
+
if (typeof carbonIntensity !== "boolean") {
|
|
147
|
+
throw new Error(
|
|
148
|
+
"perVisit expects a boolean for the carbon intensity value. Received: ".concat(carbonIntensity)
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
const co2ValuesbyComponent = this.co2byComponent(
|
|
152
|
+
energyBycomponent,
|
|
153
|
+
carbonIntensity,
|
|
154
|
+
options
|
|
155
|
+
);
|
|
156
|
+
const co2Values = Object.values(co2ValuesbyComponent);
|
|
157
|
+
const co2ValuesSum = co2Values.reduce(
|
|
158
|
+
(prevValue, currentValue) => prevValue + currentValue
|
|
159
|
+
);
|
|
160
|
+
if (segmentResults) {
|
|
161
|
+
return __spreadProps(__spreadValues({}, co2ValuesbyComponent), { total: co2ValuesSum });
|
|
162
|
+
}
|
|
163
|
+
return co2ValuesSum;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Accept a figure for bytes transferred and return the number of kilowatt hours used
|
|
167
|
+
* by the total system for this data transfer
|
|
168
|
+
*
|
|
169
|
+
* @param {number} bytes
|
|
170
|
+
* @return {number} the number of kilowatt hours used
|
|
171
|
+
*/
|
|
172
|
+
energyPerByte(bytes) {
|
|
173
|
+
const energyByComponent = this.energyPerByteByComponent(bytes);
|
|
174
|
+
const energyValues = Object.values(energyByComponent);
|
|
175
|
+
return energyValues.reduce(
|
|
176
|
+
(prevValue, currentValue) => prevValue + currentValue
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Accept a figure for bytes transferred, and return an object containing figures
|
|
181
|
+
* per system component, with the caching assumptions applied. This tries to account
|
|
182
|
+
* for webpages being loaded from a cache by browsers, so if you had a thousand page views,
|
|
183
|
+
* and tried to work out the energy per visit, the numbers would reflect the reduced amounts
|
|
184
|
+
* of transfer.
|
|
185
|
+
*
|
|
186
|
+
* @param {number} bytes - the data transferred in bytes for loading a webpage
|
|
187
|
+
* @param {number} firstView - what percentage of visits are loading this page for the first time
|
|
188
|
+
* @param {number} returnView - what percentage of visits are loading this page for subsequent times
|
|
189
|
+
* @param {number} dataReloadRatio - what percentage of a page is reloaded on each subsequent page view
|
|
190
|
+
*
|
|
191
|
+
* @return {object} Object containing the energy in kilowatt hours, keyed by system component
|
|
192
|
+
*/
|
|
193
|
+
energyPerVisitByComponent(bytes, options = {}, firstView = FIRST_TIME_VIEWING_PERCENTAGE, returnView = RETURNING_VISITOR_PERCENTAGE, dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD) {
|
|
194
|
+
if (options.dataReloadRatio || options.dataReloadRatio === 0) {
|
|
195
|
+
dataReloadRatio = options.dataReloadRatio;
|
|
196
|
+
}
|
|
197
|
+
if (options.firstVisitPercentage || options.firstVisitPercentage === 0) {
|
|
198
|
+
firstView = options.firstVisitPercentage;
|
|
199
|
+
}
|
|
200
|
+
if (options.returnVisitPercentage || options.returnVisitPercentage === 0) {
|
|
201
|
+
returnView = options.returnVisitPercentage;
|
|
202
|
+
}
|
|
203
|
+
const energyBycomponent = this.energyPerByteByComponent(bytes);
|
|
204
|
+
const cacheAdjustedSegmentEnergy = {};
|
|
205
|
+
const energyValues = Object.values(energyBycomponent);
|
|
206
|
+
for (const [key, value] of Object.entries(energyBycomponent)) {
|
|
207
|
+
cacheAdjustedSegmentEnergy["".concat(key, " - first")] = value * firstView;
|
|
208
|
+
cacheAdjustedSegmentEnergy["".concat(key, " - subsequent")] = value * returnView * dataReloadRatio;
|
|
209
|
+
}
|
|
210
|
+
return cacheAdjustedSegmentEnergy;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Accept a figure for bytes, and return the total figure for energy per visit
|
|
214
|
+
* using the default caching assumptions for loading a single website
|
|
215
|
+
*
|
|
216
|
+
* @param {number} bytes
|
|
217
|
+
* @return {number} the total energy use for the visit, after applying the caching assumptions
|
|
218
|
+
*/
|
|
219
|
+
energyPerVisit(bytes) {
|
|
220
|
+
let firstVisits = 0;
|
|
221
|
+
let subsequentVisits = 0;
|
|
222
|
+
const energyBycomponent = Object.entries(
|
|
223
|
+
this.energyPerVisitByComponent(bytes)
|
|
224
|
+
);
|
|
225
|
+
for (const [key, val] of energyBycomponent) {
|
|
226
|
+
if (key.indexOf("first") > 0) {
|
|
227
|
+
firstVisits += val;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
for (const [key, val] of energyBycomponent) {
|
|
231
|
+
if (key.indexOf("subsequent") > 0) {
|
|
232
|
+
subsequentVisits += val;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return firstVisits + subsequentVisits;
|
|
236
|
+
}
|
|
237
|
+
emissionsPerVisitInGrams(energyPerVisit, carbonintensity = GLOBAL_GRID_INTENSITY) {
|
|
238
|
+
return formatNumber(energyPerVisit * carbonintensity);
|
|
239
|
+
}
|
|
240
|
+
annualEnergyInKwh(energyPerVisit, monthlyVisitors = 1e3) {
|
|
241
|
+
return energyPerVisit * monthlyVisitors * 12;
|
|
242
|
+
}
|
|
243
|
+
annualEmissionsInGrams(co2grams, monthlyVisitors = 1e3) {
|
|
244
|
+
return co2grams * monthlyVisitors * 12;
|
|
245
|
+
}
|
|
246
|
+
annualSegmentEnergy(annualEnergy) {
|
|
247
|
+
return {
|
|
248
|
+
consumerDeviceEnergy: formatNumber(annualEnergy * END_USER_DEVICE_ENERGY),
|
|
249
|
+
networkEnergy: formatNumber(annualEnergy * NETWORK_ENERGY),
|
|
250
|
+
dataCenterEnergy: formatNumber(annualEnergy * DATACENTER_ENERGY),
|
|
251
|
+
productionEnergy: formatNumber(annualEnergy * PRODUCTION_ENERGY)
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
var sustainable_web_design_default = SustainableWebDesign;
|
|
256
|
+
export {
|
|
257
|
+
SustainableWebDesign,
|
|
258
|
+
sustainable_web_design_default as default
|
|
259
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tgwf/co2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Work out the co2 of your digital services",
|
|
5
5
|
"main": "dist/cjs/index-node.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -11,6 +11,14 @@
|
|
|
11
11
|
".": {
|
|
12
12
|
"import": "./dist/esm/index.js",
|
|
13
13
|
"require": "./dist/cjs/index-node.js"
|
|
14
|
+
},
|
|
15
|
+
"./data": {
|
|
16
|
+
"import": "./dist/esm/data.js",
|
|
17
|
+
"require": "./dist/cjs/data.js"
|
|
18
|
+
},
|
|
19
|
+
"./hosting": {
|
|
20
|
+
"import": "./dist/esm/hosting.js",
|
|
21
|
+
"require": "./dist/cjs/hosting-node.js"
|
|
14
22
|
}
|
|
15
23
|
},
|
|
16
24
|
"scripts": {
|