@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.
- package/CHANGELOG.md +26 -0
- package/dist/cjs/1byte.js +6 -0
- package/dist/cjs/1byte.js.map +1 -1
- package/dist/cjs/co2.js +42 -0
- package/dist/cjs/co2.js.map +1 -1
- package/dist/cjs/constants/index.js +4 -0
- package/dist/cjs/constants/index.js.map +1 -1
- package/dist/cjs/data/average-intensities.min.js +1 -1
- package/dist/cjs/data/average-intensities.min.js.map +2 -2
- package/dist/cjs/helpers/index.js +1 -1
- package/dist/cjs/helpers/index.js.map +1 -1
- package/dist/cjs/hosting-api.js +4 -0
- package/dist/cjs/hosting-api.js.map +1 -1
- package/dist/cjs/hosting-json.js.map +1 -1
- package/dist/cjs/hosting-json.node.js +4 -0
- package/dist/cjs/hosting-json.node.js.map +1 -1
- package/dist/cjs/hosting-node.js +4 -0
- package/dist/cjs/hosting-node.js.map +1 -1
- package/dist/cjs/hosting.js +4 -0
- package/dist/cjs/hosting.js.map +1 -1
- package/dist/cjs/index-node.js +4 -0
- package/dist/cjs/index-node.js.map +1 -1
- package/dist/cjs/index.js +9 -5
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/sustainable-web-design-v3.js +74 -0
- package/dist/cjs/sustainable-web-design-v3.js.map +1 -1
- package/dist/cjs/sustainable-web-design-v4.js +33 -1
- package/dist/cjs/sustainable-web-design-v4.js.map +2 -2
- package/dist/esm/1byte.js +6 -0
- package/dist/esm/co2.js +43 -10
- package/dist/esm/data/average-intensities.min.js +1 -1
- package/dist/esm/helpers/index.js +14 -28
- package/dist/esm/hosting-api.js +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/sustainable-web-design-v3.js +78 -4
- package/dist/esm/sustainable-web-design-v4.js +33 -1
- 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
|
|
5
|
+
var index_default = { co2, hosting, averageIntensity, marginalIntensity };
|
|
6
6
|
export {
|
|
7
7
|
averageIntensity,
|
|
8
8
|
co2,
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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[
|
|
177
|
-
cacheAdjustedSegmentEnergy[
|
|
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 =
|
|
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.
|
|
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.
|
|
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",
|