Skip to content

Commit

Permalink
Add Sustainable Web Design version 4
Browse files Browse the repository at this point in the history
  • Loading branch information
fershad authored May 31, 2024
2 parents 7e1d8f8 + 97c7d43 commit b4a7eef
Show file tree
Hide file tree
Showing 11 changed files with 924 additions and 88 deletions.
34 changes: 18 additions & 16 deletions dist/iife/index.js

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions src/co2.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
*/

import OneByte from "./1byte.js";
import SustainableWebDesign from "./sustainable-web-design.js";
import SustainableWebDesignV3 from "./sustainable-web-design-v3.js";
import SustainableWebDesignV4 from "./sustainable-web-design-v4.js";

import {
GLOBAL_GRID_INTENSITY,
Expand All @@ -70,13 +71,16 @@ import { parseOptions } from "./helpers/index.js";

class CO2 {
constructor(options) {
this.model = new SustainableWebDesign();
this.model = new SustainableWebDesignV3();
// Using optional chaining allows an empty object to be passed
// in without breaking the code.
if (options?.model === "1byte") {
this.model = new OneByte();
} else if (options?.model === "swd") {
this.model = new SustainableWebDesign();
this.model = new SustainableWebDesignV3();
if (options?.version === 4) {
this.model = new SustainableWebDesignV4();
}
} else if (options?.model) {
throw new Error(
`"${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.`
Expand Down Expand Up @@ -236,7 +240,7 @@ class CO2 {
};
} else {
throw new Error(
`The perVisitDetailed() 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.`
`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.`
);
}
}
Expand Down
29 changes: 21 additions & 8 deletions src/co2.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

import { MILLION, SWD } from "./constants/test-constants.js";
import { MILLION, SWDV3 } from "./constants/test-constants.js";

import CO2 from "./co2.js";
import { averageIntensity, marginalIntensity } from "./index.js";
Expand All @@ -15,7 +15,7 @@ describe("co2", () => {
// we include more of the system in calculations for the
// same levels of data transfer

const { MILLION_PERVISIT_GREY, MILLION_PERVISIT_GREEN } = SWD;
const { MILLION_PERVISIT_GREY, MILLION_PERVISIT_GREEN } = SWDV3;

// We're not passing in a model parameter here to check that SWD is used by default
beforeEach(() => {
Expand Down Expand Up @@ -63,7 +63,7 @@ describe("co2", () => {
MILLION_GREY_DATACENTERS,
MILLION_GREY_PRODUCTION,
MILLION_GREEN_DATACENTERS,
} = SWD;
} = SWDV3;
describe("perVisit", () => {
it("returns an object with devices, networks, data centers, and production emissions shown separately, as well as the total emissions", () => {
co2 = new CO2({ results: "segment" });
Expand Down Expand Up @@ -297,7 +297,7 @@ describe("co2", () => {
MILLION_PERBYTE_GREY_DEVICE_GRID_INTENSITY_CHANGE,
MILLION_GREY,
MILLION_PERVISIT_GREY,
} = SWD;
} = SWDV3;
const co2 = new CO2();
it("expects an object or number", () => {
expect(
Expand Down Expand Up @@ -397,7 +397,7 @@ describe("co2", () => {
MILLION_PERBYTE_GREY_DATACENTER_GRID_INTENSITY_CHANGE,
MILLION_GREY,
MILLION_PERVISIT_GREY,
} = SWD;
} = SWDV3;
const co2 = new CO2();
it("expects an object or number", () => {
expect(
Expand Down Expand Up @@ -495,7 +495,7 @@ describe("co2", () => {
MILLION_PERBYTE_GREY_NETWORK_GRID_INTENSITY_CHANGE,
MILLION_GREY,
MILLION_PERVISIT_GREY,
} = SWD;
} = SWDV3;
const co2 = new CO2();
it("expects an object or number", () => {
expect(
Expand Down Expand Up @@ -589,7 +589,7 @@ describe("co2", () => {
});

describe("Using custom caching values in SWD", () => {
const { MILLION_PERVISIT_GREY } = SWD;
const { MILLION_PERVISIT_GREY } = SWDV3;
const co2 = new CO2();
it("uses the custom value", () => {
expect(
Expand Down Expand Up @@ -637,7 +637,7 @@ describe("co2", () => {
});

describe("Using custom first and return visitor figures in SWD", () => {
const { MILLION_PERVISIT_GREY, MILLION_GREY } = SWD;
const { MILLION_PERVISIT_GREY, MILLION_GREY } = SWDV3;
const co2 = new CO2();

it("uses the custom values", () => {
Expand Down Expand Up @@ -867,4 +867,17 @@ describe("co2", () => {
expect(co2RatingSegmented.perByte(MILLION)).toHaveProperty("networkCO2");
});
});

describe("Switch versions of the Sustainable Web Design model", () => {
const co2 = new CO2({ model: "swd" });
const co2SWDV4 = new CO2({ model: "swd", version: 4 });

it("uses the SWD model version 3 by default", () => {
expect(co2.model.version).toBe(3);
});

it("uses the SWD model version 4 when specified", () => {
expect(co2SWDV4.model.version).toBe(4);
});
});
});
2 changes: 1 addition & 1 deletion src/constants/file-size.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const GIGABYTE = 1000 * 1000 * 1000;
export const GIGABYTE = 1000 * 1000 * 1000;

export default {
GIGABYTE,
Expand Down
37 changes: 29 additions & 8 deletions src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,32 @@ const FIRST_TIME_VIEWING_PERCENTAGE = 0.75;
const RETURNING_VISITOR_PERCENTAGE = 0.25;
const PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD = 0.02;

const SWDMv3Ratings = {
fifthPercentile: 0.095,
tenthPercentile: 0.186,
twentiethPercentile: 0.341,
thirtiethPercentile: 0.493,
fortiethPercentile: 0.656,
fiftiethPercentile: 0.846,
const SWDV4 = {
OPERATIONAL_KWH_PER_GB_DATACENTER: 0.055,
OPERATIONAL_KWH_PER_GB_NETWORK: 0.059,
OPERATIONAL_KWH_PER_GB_DEVICE: 0.08,
EMBODIED_KWH_PER_GB_DATACENTER: 0.012,
EMBODIED_KWH_PER_GB_NETWORK: 0.013,
EMBODIED_KWH_PER_GB_DEVICE: 0.081,
GLOBAL_GRID_INTENSITY: 494,
};

const SWDMV3_RATINGS = {
FIFTH_PERCENTILE: 0.095,
TENTH_PERCENTILE: 0.186,
TWENTIETH_PERCENTILE: 0.341,
THIRTIETH_PERCENTILE: 0.493,
FORTIETH_PERCENTILE: 0.656,
FIFTIETH_PERCENTILE: 0.846,
};

const SWDMV4_RATINGS = {
FIFTH_PERCENTILE: 0.04,
TENTH_PERCENTILE: 0.079,
TWENTIETH_PERCENTILE: 0.145,
THIRTIETH_PERCENTILE: 0.209,
FORTIETH_PERCENTILE: 0.278,
FIFTIETH_PERCENTILE: 0.359,
};

export {
Expand All @@ -45,5 +64,7 @@ export {
FIRST_TIME_VIEWING_PERCENTAGE,
RETURNING_VISITOR_PERCENTAGE,
PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
SWDMv3Ratings,
SWDV4,
SWDMV3_RATINGS,
SWDMV4_RATINGS,
};
24 changes: 23 additions & 1 deletion src/constants/test-constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const ONEBYTE = {
MILLION_GREEN: 0.23196,
};

export const SWD = {
export const SWDV3 = {
MILLION_GREY: 0.39365,
MILLION_GREEN: 0.34068,
MILLION_PERVISIT_GREY: 0.29721,
Expand Down Expand Up @@ -44,3 +44,25 @@ export const SWD = {
MILLION_PERVISIT_GREY_PRODUCTION_FIRST: 0.05701,
MILLION_PERVISIT_GREY_PRODUCTION_SECOND: 0.00034,
};

export const SWDV4 = {
PERBYTE_EMISSIONS_GB: 148.2,
PERBYTE_EMISSIONS_GB_GREEN: 121.03,
PERBYTE_EMISSIONS_GB_GREEN_PARTIAL: 134.615,
PERVISIT_EMISSIONS_GB: 140.79,
PERVISIT_EMISSIONS_GB_FIRSTVIEW: 148.2,
PERVISIT_EMISSIONS_GB_RETURNVIEW: 118.56,
PERVISIT_EMISSIONS_GB_GREEN: 114.9785,
PERVISIT_EMISSIONS_GB_GREEN_PARTIAL: 127.88425,
DC_OPERATIONAL_EMISSIONS_GB: 27.17,
NETWORK_OPERATIONAL_EMISSIONS_GB: 29.146,
DEVICE_OPERATIONAL_EMISSIONS_GB: 39.52,
TOTAL_OPERATIONAL_EMISSIONS_GB: 95.836,
DC_EMBODIED_EMISSIONS_GB: 5.928,
NETWORK_EMBODIED_EMISSIONS_GB: 6.422,
DEVICE_EMBODIED_EMISSIONS_GB: 40.014,
TOTAL_EMBODIED_EMISSIONS_GB: 52.364,
TOTAL_DC_EMISSIONS_GB: 33.098,
TOTAL_NETWORK_EMISSIONS_GB: 35.568,
TOTAL_DEVICE_EMISSIONS_GB: 79.534,
}
53 changes: 52 additions & 1 deletion src/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
FIRST_TIME_VIEWING_PERCENTAGE,
RETURNING_VISITOR_PERCENTAGE,
SWDMV3_RATINGS,
SWDMV4_RATINGS,
} from "../constants/index.js";

// Shared type definitions to be used across different files
Expand Down Expand Up @@ -194,4 +196,53 @@ function getApiRequestHeaders(comment = "") {
return { "User-Agent": `co2js/${process.env.CO2JS_VERSION} ${comment}` };
}

export { formatNumber, parseOptions, getApiRequestHeaders, lessThanEqualTo };
/**
* Returns the SWDM rating for a given CO2e value and version of the SWDM.
* @param {number} co2e - The CO2e value to rate.
* @param {number} swdmVersion - The version of the SWDM to use. Defaults to version 3.
* @returns {string} The SWDM rating.
*/

function outputRating(co2e, swdmVersion) {
let {
FIFTH_PERCENTILE,
TENTH_PERCENTILE,
TWENTIETH_PERCENTILE,
THIRTIETH_PERCENTILE,
FORTIETH_PERCENTILE,
FIFTIETH_PERCENTILE,
} = SWDMV3_RATINGS;

if (swdmVersion === 4) {
FIFTH_PERCENTILE = SWDMV4_RATINGS.FIFTH_PERCENTILE;
TENTH_PERCENTILE = SWDMV4_RATINGS.TENTH_PERCENTILE;
TWENTIETH_PERCENTILE = SWDMV4_RATINGS.TWENTIETH_PERCENTILE;
THIRTIETH_PERCENTILE = SWDMV4_RATINGS.THIRTIETH_PERCENTILE;
FORTIETH_PERCENTILE = SWDMV4_RATINGS.FORTIETH_PERCENTILE;
FIFTIETH_PERCENTILE = SWDMV4_RATINGS.FIFTIETH_PERCENTILE;
}

if (lessThanEqualTo(co2e, FIFTH_PERCENTILE)) {
return "A+";
} else if (lessThanEqualTo(co2e, TENTH_PERCENTILE)) {
return "A";
} else if (lessThanEqualTo(co2e, TWENTIETH_PERCENTILE)) {
return "B";
} else if (lessThanEqualTo(co2e, THIRTIETH_PERCENTILE)) {
return "C";
} else if (lessThanEqualTo(co2e, FORTIETH_PERCENTILE)) {
return "D";
} else if (lessThanEqualTo(co2e, FIFTIETH_PERCENTILE)) {
return "E";
} else {
return "F";
}
}

export {
formatNumber,
parseOptions,
getApiRequestHeaders,
lessThanEqualTo,
outputRating,
};
29 changes: 3 additions & 26 deletions src/sustainable-web-design.js → src/sustainable-web-design-v3.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,14 @@ import {
FIRST_TIME_VIEWING_PERCENTAGE,
RETURNING_VISITOR_PERCENTAGE,
PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
SWDMv3Ratings,
} from "./constants/index.js";
import { formatNumber, lessThanEqualTo } from "./helpers/index.js";

const {
fifthPercentile,
tenthPercentile,
twentiethPercentile,
thirtiethPercentile,
fortiethPercentile,
fiftiethPercentile,
} = SWDMv3Ratings;
import { formatNumber, outputRating } from "./helpers/index.js";

class SustainableWebDesign {
constructor(options) {
this.allowRatings = true;
this.options = options;
this.version = 3;
}

/**
Expand Down Expand Up @@ -387,21 +378,7 @@ class SustainableWebDesign {
* @returns {string} The sustainability rating, ranging from "A+" (best) to "F" (worst).
*/
ratingScale(co2e) {
if (lessThanEqualTo(co2e, fifthPercentile)) {
return "A+";
} else if (lessThanEqualTo(co2e, tenthPercentile)) {
return "A";
} else if (lessThanEqualTo(co2e, twentiethPercentile)) {
return "B";
} else if (lessThanEqualTo(co2e, thirtiethPercentile)) {
return "C";
} else if (lessThanEqualTo(co2e, fortiethPercentile)) {
return "D";
} else if (lessThanEqualTo(co2e, fiftiethPercentile)) {
return "E";
} else {
return "F";
}
return outputRating(co2e, this.version);
}
}

Expand Down
Loading

0 comments on commit b4a7eef

Please sign in to comment.