@tgwf/co2 0.16.6 → 0.16.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cjs/1byte.js +6 -0
  3. package/dist/cjs/1byte.js.map +1 -1
  4. package/dist/cjs/co2.js +42 -0
  5. package/dist/cjs/co2.js.map +1 -1
  6. package/dist/cjs/constants/index.js +4 -0
  7. package/dist/cjs/constants/index.js.map +1 -1
  8. package/dist/cjs/data/average-intensities.min.js +1 -1
  9. package/dist/cjs/data/average-intensities.min.js.map +2 -2
  10. package/dist/cjs/helpers/index.js +1 -1
  11. package/dist/cjs/helpers/index.js.map +1 -1
  12. package/dist/cjs/hosting-api.js +4 -0
  13. package/dist/cjs/hosting-api.js.map +1 -1
  14. package/dist/cjs/hosting-json.js.map +1 -1
  15. package/dist/cjs/hosting-json.node.js +4 -0
  16. package/dist/cjs/hosting-json.node.js.map +1 -1
  17. package/dist/cjs/hosting-node.js +4 -0
  18. package/dist/cjs/hosting-node.js.map +1 -1
  19. package/dist/cjs/hosting.js +4 -0
  20. package/dist/cjs/hosting.js.map +1 -1
  21. package/dist/cjs/index-node.js +4 -0
  22. package/dist/cjs/index-node.js.map +1 -1
  23. package/dist/cjs/index.js +9 -5
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/cjs/sustainable-web-design-v3.js +74 -0
  26. package/dist/cjs/sustainable-web-design-v3.js.map +1 -1
  27. package/dist/cjs/sustainable-web-design-v4.js +33 -1
  28. package/dist/cjs/sustainable-web-design-v4.js.map +2 -2
  29. package/dist/esm/1byte.js +6 -0
  30. package/dist/esm/co2.js +43 -10
  31. package/dist/esm/data/average-intensities.min.js +1 -1
  32. package/dist/esm/helpers/index.js +14 -28
  33. package/dist/esm/hosting-api.js +2 -2
  34. package/dist/esm/index.js +2 -2
  35. package/dist/esm/sustainable-web-design-v3.js +78 -4
  36. package/dist/esm/sustainable-web-design-v4.js +33 -1
  37. package/package.json +3 -3
package/dist/esm/index.js CHANGED
@@ -2,11 +2,11 @@ import co2 from "./co2.js";
2
2
  import hosting from "./hosting.js";
3
3
  import averageIntensity from "./data/average-intensities.min.js";
4
4
  import marginalIntensity from "./data/marginal-intensities-2021.min.js";
5
- var src_default = { co2, hosting, averageIntensity, marginalIntensity };
5
+ var index_default = { co2, hosting, averageIntensity, marginalIntensity };
6
6
  export {
7
7
  averageIntensity,
8
8
  co2,
9
- src_default as default,
9
+ index_default as default,
10
10
  hosting,
11
11
  marginalIntensity
12
12
  };
@@ -37,6 +37,14 @@ class SustainableWebDesign {
37
37
  this.options = options;
38
38
  this.version = 3;
39
39
  }
40
+ /**
41
+ * Accept a figure for bytes transferred and return an object representing
42
+ * the share of the total enrgy use of the entire system, broken down
43
+ * by each corresponding system component
44
+ *
45
+ * @param {number} bytes - the data transferred in bytes
46
+ * @return {object} Object containing the energy in kilowatt hours, keyed by system component
47
+ */
40
48
  energyPerByteByComponent(bytes) {
41
49
  const transferedBytesToGb = bytes / fileSize.GIGABYTE;
42
50
  const energyUsage = transferedBytesToGb * KWH_PER_GB;
@@ -47,6 +55,14 @@ class SustainableWebDesign {
47
55
  dataCenterEnergy: energyUsage * DATACENTER_ENERGY
48
56
  };
49
57
  }
58
+ /**
59
+ * Accept an object keys by the different system components, and
60
+ * return an object with the co2 figures key by the each component
61
+ *
62
+ * @param {object} energyByComponent - energy grouped by the four system components
63
+ * @param {number} [carbonIntensity] - carbon intensity to apply to the datacentre values
64
+ * @return {number} the total number in grams of CO2 equivalent emissions
65
+ */
50
66
  co2byComponent(energyByComponent, carbonIntensity = GLOBAL_GRID_INTENSITY, options = {}) {
51
67
  let deviceCarbonIntensity = GLOBAL_GRID_INTENSITY;
52
68
  let networkCarbonIntensity = GLOBAL_GRID_INTENSITY;
@@ -81,6 +97,19 @@ class SustainableWebDesign {
81
97
  }
82
98
  return returnCO2ByComponent;
83
99
  }
100
+ /**
101
+ * Accept a figure for bytes transferred and return a single figure for CO2
102
+ * emissions. Where information exists about the origin data is being
103
+ * fetched from, a different carbon intensity figure
104
+ * is applied for the data centre share of the carbon intensity.
105
+ *
106
+ * @param {number} bytes - the data transferred in bytes
107
+ * @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not
108
+ * @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component
109
+ * @param {boolean} ratingResults - a boolean indicating whether to return the rating based on the Sustainable Web Design Model
110
+ * @param {object} options - an object containing the grid intensity and first/return visitor values
111
+ * @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component
112
+ */
84
113
  perByte(bytes, carbonIntensity = false, segmentResults = false, ratingResults = false, options = {}) {
85
114
  if (bytes < 1) {
86
115
  bytes = 0;
@@ -88,7 +117,7 @@ class SustainableWebDesign {
88
117
  const energyBycomponent = this.energyPerByteByComponent(bytes, options);
89
118
  if (typeof carbonIntensity !== "boolean") {
90
119
  throw new Error(
91
- `perByte expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`
120
+ "perByte expects a boolean for the carbon intensity value. Received: ".concat(carbonIntensity)
92
121
  );
93
122
  }
94
123
  const co2ValuesbyComponent = this.co2byComponent(
@@ -118,11 +147,22 @@ class SustainableWebDesign {
118
147
  }
119
148
  return co2ValuesSum;
120
149
  }
150
+ /**
151
+ * Accept a figure for bytes transferred and return a single figure for CO2
152
+ * emissions. This method applies caching assumptions from the original Sustainable Web Design model.
153
+ *
154
+ * @param {number} bytes - the data transferred in bytes
155
+ * @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not
156
+ * @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component
157
+ * @param {boolean} ratingResults - a boolean indicating whether to return the rating based on the Sustainable Web Design Model
158
+ * @param {object} options - an object containing the grid intensity and first/return visitor values
159
+ * @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component
160
+ */
121
161
  perVisit(bytes, carbonIntensity = false, segmentResults = false, ratingResults = false, options = {}) {
122
162
  const energyBycomponent = this.energyPerVisitByComponent(bytes, options);
123
163
  if (typeof carbonIntensity !== "boolean") {
124
164
  throw new Error(
125
- `perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`
165
+ "perVisit expects a boolean for the carbon intensity value. Received: ".concat(carbonIntensity)
126
166
  );
127
167
  }
128
168
  const co2ValuesbyComponent = this.co2byComponent(
@@ -152,6 +192,13 @@ class SustainableWebDesign {
152
192
  }
153
193
  return co2ValuesSum;
154
194
  }
195
+ /**
196
+ * Accept a figure for bytes transferred and return the number of kilowatt hours used
197
+ * by the total system for this data transfer
198
+ *
199
+ * @param {number} bytes
200
+ * @return {number} the number of kilowatt hours used
201
+ */
155
202
  energyPerByte(bytes) {
156
203
  const energyByComponent = this.energyPerByteByComponent(bytes);
157
204
  const energyValues = Object.values(energyByComponent);
@@ -159,6 +206,20 @@ class SustainableWebDesign {
159
206
  (prevValue, currentValue) => prevValue + currentValue
160
207
  );
161
208
  }
209
+ /**
210
+ * Accept a figure for bytes transferred, and return an object containing figures
211
+ * per system component, with the caching assumptions applied. This tries to account
212
+ * for webpages being loaded from a cache by browsers, so if you had a thousand page views,
213
+ * and tried to work out the energy per visit, the numbers would reflect the reduced amounts
214
+ * of transfer.
215
+ *
216
+ * @param {number} bytes - the data transferred in bytes for loading a webpage
217
+ * @param {number} firstView - what percentage of visits are loading this page for the first time
218
+ * @param {number} returnView - what percentage of visits are loading this page for subsequent times
219
+ * @param {number} dataReloadRatio - what percentage of a page is reloaded on each subsequent page view
220
+ *
221
+ * @return {object} Object containing the energy in kilowatt hours, keyed by system component
222
+ */
162
223
  energyPerVisitByComponent(bytes, options = {}, firstView = FIRST_TIME_VIEWING_PERCENTAGE, returnView = RETURNING_VISITOR_PERCENTAGE, dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD) {
163
224
  if (options.dataReloadRatio || options.dataReloadRatio === 0) {
164
225
  dataReloadRatio = options.dataReloadRatio;
@@ -173,11 +234,18 @@ class SustainableWebDesign {
173
234
  const cacheAdjustedSegmentEnergy = {};
174
235
  const energyValues = Object.values(energyBycomponent);
175
236
  for (const [key, value] of Object.entries(energyBycomponent)) {
176
- cacheAdjustedSegmentEnergy[`${key} - first`] = value * firstView;
177
- cacheAdjustedSegmentEnergy[`${key} - subsequent`] = value * returnView * dataReloadRatio;
237
+ cacheAdjustedSegmentEnergy["".concat(key, " - first")] = value * firstView;
238
+ cacheAdjustedSegmentEnergy["".concat(key, " - subsequent")] = value * returnView * dataReloadRatio;
178
239
  }
179
240
  return cacheAdjustedSegmentEnergy;
180
241
  }
242
+ /**
243
+ * Accept a figure for bytes, and return the total figure for energy per visit
244
+ * using the default caching assumptions for loading a single website
245
+ *
246
+ * @param {number} bytes
247
+ * @return {number} the total energy use for the visit, after applying the caching assumptions
248
+ */
181
249
  energyPerVisit(bytes) {
182
250
  let firstVisits = 0;
183
251
  let subsequentVisits = 0;
@@ -213,6 +281,12 @@ class SustainableWebDesign {
213
281
  productionEnergy: formatNumber(annualEnergy * PRODUCTION_ENERGY)
214
282
  };
215
283
  }
284
+ /**
285
+ * Determines the rating of a website's sustainability based on its CO2 emissions.
286
+ *
287
+ * @param {number} co2e - The CO2 emissions of the website in grams.
288
+ * @returns {string} The sustainability rating, ranging from "A+" (best) to "F" (worst).
289
+ */
216
290
  ratingScale(co2e) {
217
291
  return outputRating(co2e, this.version);
218
292
  }
@@ -62,6 +62,12 @@ class SustainableWebDesign {
62
62
  this.options = options;
63
63
  this.version = 4;
64
64
  }
65
+ /**
66
+ * Calculate the operational energy of data transfer for each system segment
67
+ *
68
+ * @param {number} bytes
69
+ * @returns {object}
70
+ */
65
71
  operationalEnergyPerSegment(bytes) {
66
72
  const transferedBytesToGb = bytes / fileSize.GIGABYTE;
67
73
  const dataCenter = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_DATACENTER;
@@ -73,6 +79,13 @@ class SustainableWebDesign {
73
79
  device
74
80
  };
75
81
  }
82
+ /**
83
+ * Calculate the operational emissions of data transfer for each system segment
84
+ *
85
+ * @param {number} bytes
86
+ * @param {object} options
87
+ * @returns {object}
88
+ */
76
89
  operationalEmissions(bytes, options = {}) {
77
90
  const { dataCenter, network, device } = this.operationalEnergyPerSegment(bytes);
78
91
  let dataCenterGridIntensity = GLOBAL_GRID_INTENSITY;
@@ -99,6 +112,12 @@ class SustainableWebDesign {
99
112
  device: deviceEmissions
100
113
  };
101
114
  }
115
+ /**
116
+ * Calculate the embodied energy of data transfer for each system segment
117
+ *
118
+ * @param {number} bytes
119
+ * @returns {object}
120
+ */
102
121
  embodiedEnergyPerSegment(bytes) {
103
122
  const transferedBytesToGb = bytes / fileSize.GIGABYTE;
104
123
  const dataCenter = transferedBytesToGb * EMBODIED_KWH_PER_GB_DATACENTER;
@@ -110,6 +129,12 @@ class SustainableWebDesign {
110
129
  device
111
130
  };
112
131
  }
132
+ /**
133
+ * Calculate the embodied emissions of data transfer for each system segment
134
+ *
135
+ * @param {number} bytes
136
+ * @returns {object}
137
+ */
113
138
  embodiedEmissions(bytes) {
114
139
  const { dataCenter, network, device } = this.embodiedEnergyPerSegment(bytes);
115
140
  const dataCenterGridIntensity = GLOBAL_GRID_INTENSITY;
@@ -124,6 +149,7 @@ class SustainableWebDesign {
124
149
  device: deviceEmissions
125
150
  };
126
151
  }
152
+ // NOTE: Setting green: true should result in a greenHostingFactor of 1.0
127
153
  perByte(bytes, green = false, segmented = false, ratingResults = false, options = {}) {
128
154
  if (bytes < 1) {
129
155
  return 0;
@@ -176,7 +202,7 @@ class SustainableWebDesign {
176
202
  dataReloadRatio = options.dataReloadRatio;
177
203
  }
178
204
  const firstVisitEmissions = operationalEmissions.dataCenter * (1 - greenHostingFactor) + embodiedEmissions.dataCenter + operationalEmissions.network + embodiedEmissions.network + operationalEmissions.device + embodiedEmissions.device;
179
- const returnVisitEmissions = (operationalEmissions.dataCenter * (1 - greenHostingFactor) + embodiedEmissions.dataCenter + operationalEmissions.network + embodiedEmissions.network + operationalEmissions.device + embodiedEmissions.device) * (1 - dataReloadRatio);
205
+ const returnVisitEmissions = firstVisitEmissions * dataReloadRatio;
180
206
  const total = firstVisitEmissions * firstViewRatio + returnVisitEmissions * returnViewRatio;
181
207
  let rating = null;
182
208
  if (ratingResults) {
@@ -200,6 +226,12 @@ class SustainableWebDesign {
200
226
  }
201
227
  return total;
202
228
  }
229
+ /**
230
+ * Determines the rating of a website's sustainability based on its CO2 emissions.
231
+ *
232
+ * @param {number} co2e - The CO2 emissions of the website in grams.
233
+ * @returns {string} The sustainability rating, ranging from "A+" (best) to "F" (worst).
234
+ */
203
235
  ratingScale(co2e) {
204
236
  return outputRating(co2e, this.version);
205
237
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tgwf/co2",
3
- "version": "0.16.6",
3
+ "version": "0.16.8",
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",
@@ -14,7 +14,7 @@
14
14
  }
15
15
  },
16
16
  "scripts": {
17
- "test": "jest src",
17
+ "test": "jest src --silent",
18
18
  "test:watch": "jest --watch src",
19
19
  "lint": "eslint src",
20
20
  "lint:fix": "eslint src --fix",
@@ -46,7 +46,7 @@
46
46
  "devDependencies": {
47
47
  "@tgwf/url2green": "^0.4.1",
48
48
  "all-contributors-cli": "^6.26.1",
49
- "esbuild": "^0.14.47",
49
+ "esbuild": "^0.25.0",
50
50
  "esbuild-jest": "^0.5.0",
51
51
  "esbuild-plugin-glob": "^1.1.2",
52
52
  "eslint": "^8.15.0",