@tgwf/co2 0.11.4 → 0.12.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.
Files changed (73) hide show
  1. package/.esbuild.esm.js +1 -1
  2. package/.esbuild.node.js +1 -1
  3. package/README.md +3 -3
  4. package/dist/cjs/1byte.js +0 -0
  5. package/dist/cjs/1byte.js.map +2 -2
  6. package/dist/cjs/co2.js +67 -4
  7. package/dist/cjs/co2.js.map +2 -2
  8. package/dist/cjs/constants/file-size.js +0 -0
  9. package/dist/cjs/constants/file-size.js.map +0 -0
  10. package/dist/cjs/constants/index.js +23 -1
  11. package/dist/cjs/constants/index.js.map +2 -2
  12. package/dist/cjs/data/average-intensities-2021.min.js +0 -0
  13. package/dist/cjs/data/average-intensities-2021.min.js.map +0 -0
  14. package/dist/cjs/data/marginal-intensities-2021.min.js +0 -0
  15. package/dist/cjs/data/marginal-intensities-2021.min.js.map +0 -0
  16. package/dist/cjs/helpers/index.js +139 -1
  17. package/dist/cjs/helpers/index.js.map +2 -2
  18. package/dist/cjs/hosting-api.js +0 -0
  19. package/dist/cjs/hosting-api.js.map +0 -0
  20. package/dist/cjs/hosting-json.node.js +0 -0
  21. package/dist/cjs/hosting-json.node.js.map +0 -0
  22. package/dist/cjs/hosting-node.js +0 -0
  23. package/dist/cjs/hosting-node.js.map +0 -0
  24. package/dist/cjs/hosting.js +0 -0
  25. package/dist/cjs/hosting.js.map +0 -0
  26. package/dist/cjs/index-node.js +0 -0
  27. package/dist/cjs/index-node.js.map +0 -0
  28. package/dist/cjs/index.js +0 -0
  29. package/dist/cjs/index.js.map +0 -0
  30. package/dist/cjs/package.json +0 -0
  31. package/dist/cjs/sustainable-web-design.js +67 -49
  32. package/dist/cjs/sustainable-web-design.js.map +2 -2
  33. package/dist/esm/1byte.js +0 -0
  34. package/dist/esm/co2.js +70 -4
  35. package/dist/esm/constants/file-size.js +0 -0
  36. package/dist/esm/constants/index.js +23 -1
  37. package/dist/esm/data/average-intensities-2021.min.js +0 -0
  38. package/dist/esm/data/marginal-intensities-2021.min.js +0 -0
  39. package/dist/esm/helpers/index.js +144 -1
  40. package/dist/esm/hosting-api.js +0 -0
  41. package/dist/esm/hosting.js +0 -0
  42. package/dist/esm/index.js +0 -0
  43. package/dist/esm/package.json +0 -0
  44. package/dist/esm/sustainable-web-design.js +90 -41
  45. package/dist/iife/index.js +19 -3
  46. package/dist/iife/index.js.map +3 -3
  47. package/package.json +1 -1
  48. package/src/1byte.js +7 -0
  49. package/src/co2.js +157 -4
  50. package/src/constants/index.js +38 -1
  51. package/src/helpers/index.js +173 -1
  52. package/src/sustainable-web-design.js +113 -72
  53. package/dist/cjs/1byte.test.js +0 -27
  54. package/dist/cjs/1byte.test.js.map +0 -7
  55. package/dist/cjs/co2.test.js +0 -281
  56. package/dist/cjs/co2.test.js.map +0 -7
  57. package/dist/cjs/hosting-api.test.js +0 -47
  58. package/dist/cjs/hosting-api.test.js.map +0 -7
  59. package/dist/cjs/hosting-database.node.test.js +0 -36
  60. package/dist/cjs/hosting-database.node.test.js.map +0 -7
  61. package/dist/cjs/hosting-json.node.test.js +0 -43
  62. package/dist/cjs/hosting-json.node.test.js.map +0 -7
  63. package/dist/cjs/hosting.test.js +0 -67
  64. package/dist/cjs/hosting.test.js.map +0 -7
  65. package/dist/cjs/sustainable-web-design.test.js +0 -84
  66. package/dist/cjs/sustainable-web-design.test.js.map +0 -7
  67. package/dist/esm/1byte.test.js +0 -11
  68. package/dist/esm/co2.test.js +0 -265
  69. package/dist/esm/hosting-api.test.js +0 -31
  70. package/dist/esm/hosting-database.node.test.js +0 -20
  71. package/dist/esm/hosting-json.node.test.js +0 -27
  72. package/dist/esm/hosting.test.js +0 -51
  73. package/dist/esm/sustainable-web-design.test.js +0 -68
@@ -1,3 +1,40 @@
1
1
  import fileSize from "./file-size.js";
2
+ import testConstants from "./test-constants.js";
2
3
 
3
- export { fileSize };
4
+ // SUSTAINABLE WEB DESIGN CONSTANTS
5
+ // this refers to the estimated total energy use for the internet around 2000 TWh,
6
+ // divided by the total transfer it enables around 2500 exabytes
7
+ const KWH_PER_GB = 0.81;
8
+
9
+ // these constants outline how the energy is attributed to
10
+ // different parts of the system in the SWD model
11
+ const END_USER_DEVICE_ENERGY = 0.52;
12
+ const NETWORK_ENERGY = 0.14;
13
+ const DATACENTER_ENERGY = 0.15;
14
+ const PRODUCTION_ENERGY = 0.19;
15
+
16
+ // These carbon intensity figures https://ember-climate.org/data/data-explorer
17
+ // - Global carbon intensity for 2021
18
+ const GLOBAL_GRID_INTENSITY = 442;
19
+ const RENEWABLES_GRID_INTENSITY = 50;
20
+
21
+ // Taken from: https://gitlab.com/wholegrain/carbon-api-2-0/-/blob/master/includes/carbonapi.php
22
+
23
+ const FIRST_TIME_VIEWING_PERCENTAGE = 0.75;
24
+ const RETURNING_VISITOR_PERCENTAGE = 0.25;
25
+ const PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD = 0.02;
26
+
27
+ export {
28
+ fileSize,
29
+ testConstants,
30
+ KWH_PER_GB,
31
+ END_USER_DEVICE_ENERGY,
32
+ NETWORK_ENERGY,
33
+ DATACENTER_ENERGY,
34
+ PRODUCTION_ENERGY,
35
+ GLOBAL_GRID_INTENSITY,
36
+ RENEWABLES_GRID_INTENSITY,
37
+ FIRST_TIME_VIEWING_PERCENTAGE,
38
+ RETURNING_VISITOR_PERCENTAGE,
39
+ PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
40
+ };
@@ -1,3 +1,175 @@
1
+ import { averageIntensity } from "../index.js";
2
+ import {
3
+ GLOBAL_GRID_INTENSITY,
4
+ PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
5
+ FIRST_TIME_VIEWING_PERCENTAGE,
6
+ RETURNING_VISITOR_PERCENTAGE,
7
+ } from "../constants/index.js";
1
8
  const formatNumber = (num) => parseFloat(num.toFixed(2));
2
9
 
3
- export { formatNumber };
10
+ function parseOptions(options) {
11
+ // CHeck that it is an object
12
+ if (typeof options !== "object") {
13
+ throw new Error("Options must be an object");
14
+ }
15
+
16
+ const adjustments = {};
17
+
18
+ if (options?.gridIntensity) {
19
+ adjustments.gridIntensity = {};
20
+ const { device, dataCenter, network } = options.gridIntensity;
21
+ if (device) {
22
+ if (typeof device === "object") {
23
+ if (!averageIntensity.data[device.country?.toUpperCase()]) {
24
+ console.warn(
25
+ `"${device.country}" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. \nFalling back to global average grid intensity.`
26
+ );
27
+ adjustments.gridIntensity["device"] = {
28
+ value: GLOBAL_GRID_INTENSITY,
29
+ };
30
+ }
31
+ adjustments.gridIntensity["device"] = {
32
+ country: device.country,
33
+ value: parseFloat(
34
+ averageIntensity.data[device.country?.toUpperCase()]
35
+ ),
36
+ };
37
+ } else if (typeof device === "number") {
38
+ adjustments.gridIntensity["device"] = {
39
+ value: device,
40
+ };
41
+ } else {
42
+ adjustments.gridIntensity["device"] = {
43
+ value: GLOBAL_GRID_INTENSITY,
44
+ };
45
+ console.warn(
46
+ `The device grid intensity must be a number or an object. You passed in a ${typeof device}. \nFalling back to global average grid intensity.`
47
+ );
48
+ }
49
+ }
50
+ if (dataCenter) {
51
+ if (typeof dataCenter === "object") {
52
+ if (!averageIntensity.data[dataCenter.country?.toUpperCase()]) {
53
+ console.warn(
54
+ `"${dataCenter.country}" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. \nFalling back to global average grid intensity.`
55
+ );
56
+ adjustments.gridIntensity["dataCenter"] = {
57
+ value: GLOBAL_GRID_INTENSITY,
58
+ };
59
+ }
60
+ adjustments.gridIntensity["dataCenter"] = {
61
+ country: dataCenter.country,
62
+ value: parseFloat(
63
+ averageIntensity.data[dataCenter.country?.toUpperCase()]
64
+ ),
65
+ };
66
+ } else if (typeof dataCenter === "number") {
67
+ adjustments.gridIntensity["dataCenter"] = {
68
+ value: dataCenter,
69
+ };
70
+ } else {
71
+ adjustments.gridIntensity["dataCenter"] = {
72
+ value: GLOBAL_GRID_INTENSITY,
73
+ };
74
+ console.warn(
75
+ `The data center grid intensity must be a number or an object. You passed in a ${typeof dataCenter}. \nFalling back to global average grid intensity.`
76
+ );
77
+ }
78
+ }
79
+ if (network) {
80
+ if (typeof network === "object") {
81
+ if (!averageIntensity.data[network.country?.toUpperCase()]) {
82
+ console.warn(
83
+ `"${network.country}" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. Falling back to global average grid intensity. \nFalling back to global average grid intensity.`
84
+ );
85
+ adjustments.gridIntensity["network"] = {
86
+ value: GLOBAL_GRID_INTENSITY,
87
+ };
88
+ }
89
+ adjustments.gridIntensity["network"] = {
90
+ country: network.country,
91
+ value: parseFloat(
92
+ averageIntensity.data[network.country?.toUpperCase()]
93
+ ),
94
+ };
95
+ } else if (typeof network === "number") {
96
+ adjustments.gridIntensity["network"] = {
97
+ value: network,
98
+ };
99
+ } else {
100
+ adjustments.gridIntensity["network"] = {
101
+ value: GLOBAL_GRID_INTENSITY,
102
+ };
103
+ console.warn(
104
+ `The network grid intensity must be a number or an object. You passed in a ${typeof network}. \nFalling back to global average grid intensity.`
105
+ );
106
+ }
107
+ }
108
+ }
109
+
110
+ if (options?.dataReloadRatio) {
111
+ if (typeof options.dataReloadRatio === "number") {
112
+ if (options.dataReloadRatio >= 0 && options.dataReloadRatio <= 1) {
113
+ adjustments.dataReloadRatio = options.dataReloadRatio;
114
+ } else {
115
+ adjustments.dataReloadRatio =
116
+ PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;
117
+ console.warn(
118
+ `The dataReloadRatio option must be a number between 0 and 1. You passed in ${options.dataReloadRatio}. \nFalling back to default value.`
119
+ );
120
+ }
121
+ } else {
122
+ adjustments.dataReloadRatio =
123
+ PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;
124
+ console.warn(
125
+ `The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}. \nFalling back to default value.`
126
+ );
127
+ }
128
+ }
129
+
130
+ if (options?.firstVisitPercentage) {
131
+ if (typeof options.firstVisitPercentage === "number") {
132
+ if (
133
+ options.firstVisitPercentage >= 0 &&
134
+ options.firstVisitPercentage <= 1
135
+ ) {
136
+ adjustments.firstVisitPercentage = options.firstVisitPercentage;
137
+ } else {
138
+ adjustments.firstVisitPercentage = FIRST_TIME_VIEWING_PERCENTAGE;
139
+ console.warn(
140
+ `The firstVisitPercentage option must be a number between 0 and 1. You passed in ${options.firstVisitPercentage}. \nFalling back to default value.`
141
+ );
142
+ }
143
+ } else {
144
+ adjustments.firstVisitPercentage = FIRST_TIME_VIEWING_PERCENTAGE;
145
+ console.warn(
146
+ `The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}. \nFalling back to default value.`
147
+ );
148
+ }
149
+ }
150
+
151
+ if (options?.returnVisitPercentage) {
152
+ if (typeof options.returnVisitPercentage === "number") {
153
+ if (
154
+ options.returnVisitPercentage >= 0 &&
155
+ options.returnVisitPercentage <= 1
156
+ ) {
157
+ adjustments.returnVisitPercentage = options.returnVisitPercentage;
158
+ } else {
159
+ adjustments.returnVisitPercentage = RETURNING_VISITOR_PERCENTAGE;
160
+ console.warn(
161
+ `The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}. \nFalling back to default value.`
162
+ );
163
+ }
164
+ } else {
165
+ adjustments.returnVisitPercentage = RETURNING_VISITOR_PERCENTAGE;
166
+ console.warn(
167
+ `The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}. \nFalling back to default value.`
168
+ );
169
+ }
170
+ }
171
+
172
+ return adjustments;
173
+ }
174
+
175
+ export { formatNumber, parseOptions };
@@ -6,36 +6,25 @@
6
6
  * Updated calculations and figures from
7
7
  * https://sustainablewebdesign.org/calculating-digital-emissions/
8
8
  *
9
- *
10
9
  */
11
10
  import debugFactory from "debug";
12
11
  const log = debugFactory("tgwf:sustainable-web-design");
13
12
 
14
- import { fileSize } from "./constants/index.js";
13
+ import {
14
+ fileSize,
15
+ KWH_PER_GB,
16
+ END_USER_DEVICE_ENERGY,
17
+ NETWORK_ENERGY,
18
+ DATACENTER_ENERGY,
19
+ PRODUCTION_ENERGY,
20
+ GLOBAL_GRID_INTENSITY,
21
+ RENEWABLES_GRID_INTENSITY,
22
+ FIRST_TIME_VIEWING_PERCENTAGE,
23
+ RETURNING_VISITOR_PERCENTAGE,
24
+ PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
25
+ } from "./constants/index.js";
15
26
  import { formatNumber } from "./helpers/index.js";
16
27
 
17
- // this refers to the estimated total energy use for the internet around 2000 TWh,
18
- // divided by the total transfer it enables around 2500 exabytes
19
- const KWH_PER_GB = 0.81;
20
-
21
- // these constants outline how the energy is attributed to
22
- // different parts of the system in the SWD model
23
- const END_USER_DEVICE_ENERGY = 0.52;
24
- const NETWORK_ENERGY = 0.14;
25
- const DATACENTER_ENERGY = 0.15;
26
- const PRODUCTION_ENERGY = 0.19;
27
-
28
- // These carbon intensity figures https://ember-climate.org/data/data-explorer
29
- // - Global carbon intensity for 2021
30
- const GLOBAL_INTENSITY = 442;
31
- const RENEWABLES_INTENSITY = 50;
32
-
33
- // Taken from: https://gitlab.com/wholegrain/carbon-api-2-0/-/blob/master/includes/carbonapi.php
34
-
35
- const FIRST_TIME_VIEWING_PERCENTAGE = 0.75;
36
- const RETURNING_VISITOR_PERCENTAGE = 0.25;
37
- const PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD = 0.02;
38
-
39
28
  class SustainableWebDesign {
40
29
  constructor(options) {
41
30
  this.options = options;
@@ -65,24 +54,61 @@ class SustainableWebDesign {
65
54
  * Accept an object keys by the different system components, and
66
55
  * return an object with the co2 figures key by the each component
67
56
  *
68
- * @param {object} energyBycomponent - energy grouped by the four system components
57
+ * @param {object} energyByComponent - energy grouped by the four system components
69
58
  * @param {number} [carbonIntensity] - carbon intensity to apply to the datacentre values
70
59
  * @return {number} the total number in grams of CO2 equivalent emissions
71
60
  */
72
- co2byComponent(energyBycomponent, carbonIntensity = GLOBAL_INTENSITY) {
61
+ co2byComponent(
62
+ energyByComponent,
63
+ carbonIntensity = GLOBAL_GRID_INTENSITY,
64
+ options = {}
65
+ ) {
66
+ let deviceCarbonIntensity = GLOBAL_GRID_INTENSITY;
67
+ let networkCarbonIntensity = GLOBAL_GRID_INTENSITY;
68
+ let dataCenterCarbonIntensity = GLOBAL_GRID_INTENSITY;
69
+
70
+ let globalEmissions = GLOBAL_GRID_INTENSITY;
71
+
72
+ if (options?.gridIntensity) {
73
+ const { device, network, dataCenter } = options.gridIntensity;
74
+
75
+ if (device?.value) {
76
+ deviceCarbonIntensity = device.value;
77
+ }
78
+ if (network?.value) {
79
+ networkCarbonIntensity = network.value;
80
+ }
81
+ // If the user has set a carbon intensity value for the datacentre, then that overrides everything and is used
82
+ if (dataCenter?.value) {
83
+ dataCenterCarbonIntensity = dataCenter.value;
84
+ }
85
+ }
86
+
87
+ // If the user passes in a TRUE value (green web host), then use the renewables intensity value
88
+ if (carbonIntensity === true) {
89
+ dataCenterCarbonIntensity = RENEWABLES_GRID_INTENSITY;
90
+ }
91
+
73
92
  const returnCO2ByComponent = {};
74
- for (const [key, value] of Object.entries(energyBycomponent)) {
93
+ for (const [key, value] of Object.entries(energyByComponent)) {
75
94
  // we update the datacentre, as that's what we have information
76
95
  // about.
77
96
  if (key.startsWith("dataCenterEnergy")) {
78
- returnCO2ByComponent[key] = value * carbonIntensity;
97
+ returnCO2ByComponent[key.replace("Energy", "CO2")] =
98
+ value * dataCenterCarbonIntensity;
99
+ } else if (key.startsWith("consumerDeviceEnergy")) {
100
+ returnCO2ByComponent[key.replace("Energy", "CO2")] =
101
+ value * deviceCarbonIntensity;
102
+ } else if (key.startsWith("networkEnergy")) {
103
+ returnCO2ByComponent[key.replace("Energy", "CO2")] =
104
+ value * networkCarbonIntensity;
79
105
  } else {
80
- // We don't have info about the device location,
81
- // nor the network path used, nor the production emissions
82
- // so we revert to global figures
83
- returnCO2ByComponent[key] = value * GLOBAL_INTENSITY;
106
+ // Use the global intensity for the remaining segments
107
+ returnCO2ByComponent[key.replace("Energy", "CO2")] =
108
+ value * globalEmissions;
84
109
  }
85
110
  }
111
+
86
112
  return returnCO2ByComponent;
87
113
  }
88
114
 
@@ -96,38 +122,38 @@ class SustainableWebDesign {
96
122
  * @param {number} `carbonIntensity` the carbon intensity for datacentre (average figures, not marginal ones)
97
123
  * @return {number} the total number in grams of CO2 equivalent emissions
98
124
  */
99
- perByte(bytes, carbonIntensity = GLOBAL_INTENSITY) {
100
- const energyBycomponent = this.energyPerByteByComponent(bytes);
101
-
102
- // when faced with falsy values, fallback to global intensity
103
- if (Boolean(carbonIntensity) === false) {
104
- carbonIntensity = GLOBAL_INTENSITY;
105
- }
106
- // if we have a boolean, we have a green result from the green web checker
107
- // use the renewables intensity
108
- if (carbonIntensity === true) {
109
- carbonIntensity = RENEWABLES_INTENSITY;
110
- }
125
+ perByte(
126
+ bytes,
127
+ carbonIntensity = false,
128
+ segmentResults = false,
129
+ options = {}
130
+ ) {
131
+ const energyBycomponent = this.energyPerByteByComponent(bytes, options);
111
132
 
112
133
  // otherwise when faced with non numeric values throw an error
113
- if (typeof carbonIntensity !== "number") {
134
+ if (typeof carbonIntensity !== "boolean") {
114
135
  throw new Error(
115
- `perByte expects a numeric value or boolean for the carbon intensity value. Received: ${carbonIntensity}`
136
+ `perByte expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`
116
137
  );
117
138
  }
118
139
 
119
140
  const co2ValuesbyComponent = this.co2byComponent(
120
141
  energyBycomponent,
121
- carbonIntensity
142
+ carbonIntensity,
143
+ options
122
144
  );
123
145
 
124
146
  // pull out our values…
125
147
  const co2Values = Object.values(co2ValuesbyComponent);
126
-
127
- // so we can return their sum
128
- return co2Values.reduce(
148
+ const co2ValuesSum = co2Values.reduce(
129
149
  (prevValue, currentValue) => prevValue + currentValue
130
150
  );
151
+
152
+ if (segmentResults) {
153
+ return { ...co2ValuesbyComponent, total: co2ValuesSum };
154
+ }
155
+
156
+ return co2ValuesSum;
131
157
  }
132
158
 
133
159
  /**
@@ -138,38 +164,39 @@ class SustainableWebDesign {
138
164
  * @param {number} `carbonIntensity` the carbon intensity for datacentre (average figures, not marginal ones)
139
165
  * @return {number} the total number in grams of CO2 equivalent emissions
140
166
  */
141
- perVisit(bytes, carbonIntensity = GLOBAL_INTENSITY) {
142
- const energyBycomponent = this.energyPerVisitByComponent(bytes);
143
-
144
- // when faced with falsy values, fallback to global intensity
145
- if (Boolean(carbonIntensity) === false) {
146
- carbonIntensity = GLOBAL_INTENSITY;
147
- }
148
- // if we have a boolean, we have a green result from the green web checker
149
- // use the renewables intensity
150
- if (carbonIntensity === true) {
151
- carbonIntensity = RENEWABLES_INTENSITY;
152
- }
167
+ perVisit(
168
+ bytes,
169
+ carbonIntensity = false,
170
+ segmentResults = false,
171
+ options = {}
172
+ ) {
173
+ const energyBycomponent = this.energyPerVisitByComponent(bytes, options);
153
174
 
154
- // otherwise when faced with non numeric values throw an error
155
- if (typeof carbonIntensity !== "number") {
175
+ if (typeof carbonIntensity !== "boolean") {
176
+ // otherwise when faced with non numeric values throw an error
156
177
  throw new Error(
157
- `perVisit expects a numeric value or boolean for the carbon intensity value. Received: ${carbonIntensity}`
178
+ `perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`
158
179
  );
159
180
  }
160
181
 
161
182
  const co2ValuesbyComponent = this.co2byComponent(
162
183
  energyBycomponent,
163
- carbonIntensity
184
+ carbonIntensity,
185
+ options
164
186
  );
165
187
 
166
188
  // pull out our values…
167
189
  const co2Values = Object.values(co2ValuesbyComponent);
168
-
169
- // so we can return their sum
170
- return co2Values.reduce(
190
+ const co2ValuesSum = co2Values.reduce(
171
191
  (prevValue, currentValue) => prevValue + currentValue
172
192
  );
193
+
194
+ if (segmentResults) {
195
+ return { ...co2ValuesbyComponent, total: co2ValuesSum };
196
+ }
197
+
198
+ // so we can return their sum
199
+ return co2ValuesSum;
173
200
  }
174
201
 
175
202
  /**
@@ -207,10 +234,23 @@ class SustainableWebDesign {
207
234
  */
208
235
  energyPerVisitByComponent(
209
236
  bytes,
237
+ options = {},
210
238
  firstView = FIRST_TIME_VIEWING_PERCENTAGE,
211
239
  returnView = RETURNING_VISITOR_PERCENTAGE,
212
240
  dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD
213
241
  ) {
242
+ if (options.dataReloadRatio) {
243
+ dataReloadRatio = options.dataReloadRatio;
244
+ }
245
+
246
+ if (options.firstVisitPercentage) {
247
+ firstView = options.firstVisitPercentage;
248
+ }
249
+
250
+ if (options.returnVisitPercentage) {
251
+ returnView = options.returnVisitPercentage;
252
+ }
253
+
214
254
  const energyBycomponent = this.energyPerByteByComponent(bytes);
215
255
  const cacheAdjustedSegmentEnergy = {};
216
256
 
@@ -264,9 +304,10 @@ class SustainableWebDesign {
264
304
  return firstVisits + subsequentVisits;
265
305
  }
266
306
 
267
- // TODO: this method looks like it applies the carbon intensity
268
- // change to the *entire* system, not just the datacenter.
269
- emissionsPerVisitInGrams(energyPerVisit, carbonintensity = GLOBAL_INTENSITY) {
307
+ emissionsPerVisitInGrams(
308
+ energyPerVisit,
309
+ carbonintensity = GLOBAL_GRID_INTENSITY
310
+ ) {
270
311
  return formatNumber(energyPerVisit * carbonintensity);
271
312
  }
272
313
 
@@ -1,27 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
17
- var import_byte = __toESM(require("./1byte.js"));
18
- describe("onebyte", () => {
19
- describe("perByte", () => {
20
- it("returns a simple average of the different networks", () => {
21
- const expected_val = 488e-12 .toFixed(12);
22
- const instance = new import_byte.default();
23
- expect(instance.KWH_PER_BYTE_FOR_NETWORK.toFixed(12)).toBe(expected_val);
24
- });
25
- });
26
- });
27
- //# sourceMappingURL=1byte.test.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/1byte.test.js"],
4
- "sourcesContent": ["\"use strict\";\n\nimport OneByte from \"./1byte.js\";\n\ndescribe(\"onebyte\", () => {\n describe(\"perByte\", () => {\n it(\"returns a simple average of the different networks\", () => {\n // we limit this to 12 figures with toFixed(12), because\n // we have a recurring 333333 afterwards\n // 4.88e-10 is the same as 0.000000000488\n const expected_val = (0.000000000488).toFixed(12);\n const instance = new OneByte();\n\n expect(instance.KWH_PER_BYTE_FOR_NETWORK.toFixed(12)).toBe(expected_val);\n });\n });\n});\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;AAEA,kBAAoB;AAEpB,SAAS,WAAW,MAAM;AACxB,WAAS,WAAW,MAAM;AACxB,OAAG,sDAAsD,MAAM;AAI7D,YAAM,eAAgB,SAAgB,QAAQ,EAAE;AAChD,YAAM,WAAW,IAAI,oBAAQ;AAE7B,aAAO,SAAS,yBAAyB,QAAQ,EAAE,CAAC,EAAE,KAAK,YAAY;AAAA,IACzE,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
6
- "names": []
7
- }