mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 04:05:46 +01:00
MISC: Use structuredClone() for deep cloning (#1077)
This commit is contained in:
parent
6bd50e6f24
commit
fd5b0f8241
@ -1,10 +1,13 @@
|
|||||||
import JSDOMEnvironment from "jest-environment-jsdom";
|
import JSDOMEnvironment from "jest-environment-jsdom";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
// https://github.com/facebook/jest/blob/v29.4.3/website/versioned_docs/version-29.4/Configuration.md#testenvironment-string
|
// https://github.com/facebook/jest/blob/v29.4.3/website/versioned_docs/version-29.4/Configuration.md#testenvironment-string
|
||||||
export default class FixJSDOMEnvironment extends JSDOMEnvironment {
|
export default class FixJSDOMEnvironment extends JSDOMEnvironment {
|
||||||
constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
|
constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
|
||||||
super(...args);
|
super(...args);
|
||||||
|
|
||||||
|
// TODO Tests aren't polyfilled.
|
||||||
|
this.global.structuredClone = cloneDeep;
|
||||||
// FIXME https://github.com/nodejs/node/issues/35889
|
// FIXME https://github.com/nodejs/node/issues/35889
|
||||||
// Add missing importActual() function to mirror requireActual(),
|
// Add missing importActual() function to mirror requireActual(),
|
||||||
// which lets us work around the ESM bug.
|
// which lets us work around the ESM bug.
|
||||||
|
@ -19,7 +19,6 @@ import {
|
|||||||
getBoardFromSimplifiedBoardState,
|
getBoardFromSimplifiedBoardState,
|
||||||
} from "../boardAnalysis/boardAnalysis";
|
} from "../boardAnalysis/boardAnalysis";
|
||||||
import { endGoGame } from "../boardAnalysis/scoring";
|
import { endGoGame } from "../boardAnalysis/scoring";
|
||||||
import { cloneDeep } from "lodash";
|
|
||||||
import { addObstacles, resetCoordinates, rotate90Degrees } from "./offlineNodes";
|
import { addObstacles, resetCoordinates, rotate90Degrees } from "./offlineNodes";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -276,7 +275,7 @@ export function getEmptySpaces(boardState: BoardState): PointState[] {
|
|||||||
* Makes a deep copy of the given board state
|
* Makes a deep copy of the given board state
|
||||||
*/
|
*/
|
||||||
export function getStateCopy(initialState: BoardState) {
|
export function getStateCopy(initialState: BoardState) {
|
||||||
const boardState = cloneDeep(initialState);
|
const boardState = structuredClone(initialState);
|
||||||
|
|
||||||
boardState.history = [...initialState.history];
|
boardState.history = [...initialState.history];
|
||||||
boardState.previousPlayer = initialState.previousPlayer;
|
boardState.previousPlayer = initialState.previousPlayer;
|
||||||
|
@ -95,7 +95,7 @@ import { INetscriptExtra } from "./NetscriptFunctions/Extra";
|
|||||||
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
||||||
import { getBitNodeMultipliers } from "./BitNode/BitNode";
|
import { getBitNodeMultipliers } from "./BitNode/BitNode";
|
||||||
import { assert, arrayAssert, stringAssert, objectAssert } from "./utils/helpers/typeAssertion";
|
import { assert, arrayAssert, stringAssert, objectAssert } from "./utils/helpers/typeAssertion";
|
||||||
import { cloneDeep, escapeRegExp } from "lodash";
|
import { escapeRegExp } from "lodash";
|
||||||
import numeral from "numeral";
|
import numeral from "numeral";
|
||||||
import { clearPort, peekPort, portHandle, readPort, tryWritePort, writePort, nextPortWrite } from "./NetscriptPort";
|
import { clearPort, peekPort, portHandle, readPort, tryWritePort, writePort, nextPortWrite } from "./NetscriptPort";
|
||||||
import { FilePath, resolveFilePath } from "./Paths/FilePath";
|
import { FilePath, resolveFilePath } from "./Paths/FilePath";
|
||||||
@ -1679,17 +1679,17 @@ export const ns: InternalAPI<NSFull> = {
|
|||||||
getPlayer: () => () => {
|
getPlayer: () => () => {
|
||||||
const data = {
|
const data = {
|
||||||
// Person
|
// Person
|
||||||
hp: cloneDeep(Player.hp),
|
hp: structuredClone(Player.hp),
|
||||||
skills: cloneDeep(Player.skills),
|
skills: structuredClone(Player.skills),
|
||||||
exp: cloneDeep(Player.exp),
|
exp: structuredClone(Player.exp),
|
||||||
mults: cloneDeep(Player.mults),
|
mults: structuredClone(Player.mults),
|
||||||
city: Player.city,
|
city: Player.city,
|
||||||
// Player-specific
|
// Player-specific
|
||||||
numPeopleKilled: Player.numPeopleKilled,
|
numPeopleKilled: Player.numPeopleKilled,
|
||||||
money: Player.money,
|
money: Player.money,
|
||||||
location: Player.location,
|
location: Player.location,
|
||||||
totalPlaytime: Player.totalPlaytime,
|
totalPlaytime: Player.totalPlaytime,
|
||||||
jobs: cloneDeep(Player.jobs),
|
jobs: structuredClone(Player.jobs),
|
||||||
factions: Player.factions.slice(),
|
factions: Player.factions.slice(),
|
||||||
entropy: Player.entropy,
|
entropy: Player.entropy,
|
||||||
};
|
};
|
||||||
|
@ -65,11 +65,7 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
|||||||
const filename = helpers.string(ctx, "filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||||
const contract = getCodingContract(ctx, hostname, filename);
|
const contract = getCodingContract(ctx, hostname, filename);
|
||||||
const data = contract.getData();
|
return structuredClone(contract.getData());
|
||||||
if (Array.isArray(data)) {
|
|
||||||
// For multi-dimensional arrays, we have to copy the internal arrays as well
|
|
||||||
return JSON.parse(JSON.stringify(data));
|
|
||||||
} else return data;
|
|
||||||
},
|
},
|
||||||
getDescription: (ctx) => (_filename, _hostname?) => {
|
getDescription: (ctx) => (_filename, _hostname?) => {
|
||||||
const filename = helpers.string(ctx, "filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
|
@ -6,7 +6,7 @@ import { Material } from "../Corporation/Material";
|
|||||||
import { Warehouse } from "../Corporation/Warehouse";
|
import { Warehouse } from "../Corporation/Warehouse";
|
||||||
import { Division } from "../Corporation/Division";
|
import { Division } from "../Corporation/Division";
|
||||||
import { Corporation, CorporationResolvers } from "../Corporation/Corporation";
|
import { Corporation, CorporationResolvers } from "../Corporation/Corporation";
|
||||||
import { cloneDeep, omit } from "lodash";
|
import { omit } from "lodash";
|
||||||
import { setDeprecatedProperties } from "../utils/DeprecationHelper";
|
import { setDeprecatedProperties } from "../utils/DeprecationHelper";
|
||||||
import {
|
import {
|
||||||
Corporation as NSCorporation,
|
Corporation as NSCorporation,
|
||||||
@ -248,7 +248,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
|
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const exports = cloneDeep(material.exports);
|
const exports = structuredClone(material.exports);
|
||||||
return {
|
return {
|
||||||
marketPrice: material.marketPrice,
|
marketPrice: material.marketPrice,
|
||||||
desiredSellPrice: material.desiredSellPrice,
|
desiredSellPrice: material.desiredSellPrice,
|
||||||
@ -277,7 +277,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
competition: corporation.unlocks.has(CorpUnlockName.MarketDataCompetition) ? product.competition : undefined,
|
competition: corporation.unlocks.has(CorpUnlockName.MarketDataCompetition) ? product.competition : undefined,
|
||||||
rating: product.rating,
|
rating: product.rating,
|
||||||
effectiveRating: cityData.effectiveRating,
|
effectiveRating: cityData.effectiveRating,
|
||||||
stats: cloneDeep(product.stats),
|
stats: structuredClone(product.stats),
|
||||||
productionCost: cityData.productionCost,
|
productionCost: cityData.productionCost,
|
||||||
desiredSellPrice: cityData.desiredSellPrice,
|
desiredSellPrice: cityData.desiredSellPrice,
|
||||||
desiredSellAmount: cityData.desiredSellAmount,
|
desiredSellAmount: cityData.desiredSellAmount,
|
||||||
@ -626,21 +626,21 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
|||||||
hasCorporation: () => () => !!Player.corporation,
|
hasCorporation: () => () => !!Player.corporation,
|
||||||
getConstants: (ctx) => () => {
|
getConstants: (ctx) => () => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
/* TODO 2.2: possibly just rework the whole corp constants structure to be more readable, and just use cloneDeep
|
/* TODO 2.2: possibly just rework the whole corp constants structure to be more readable, and just use
|
||||||
* to provide it directly to player.
|
* structuredClone to provide it directly to player.
|
||||||
* TODO 2.2: Roll product information into industriesData, there's no reason to look up a product separately */
|
* TODO 2.2: Roll product information into industriesData, there's no reason to look up a product separately */
|
||||||
// TODO: add functions for getting materialInfo and research info
|
// TODO: add functions for getting materialInfo and research info
|
||||||
return cloneDeep(omit(corpConstants, "fundingRoundShares", "fundingRoundMultiplier", "valuationLength"));
|
return structuredClone(omit(corpConstants, "fundingRoundShares", "fundingRoundMultiplier", "valuationLength"));
|
||||||
},
|
},
|
||||||
getIndustryData: (ctx) => (_industryName) => {
|
getIndustryData: (ctx) => (_industryName) => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const industryName = getEnumHelper("IndustryType").nsGetMember(ctx, _industryName, "industryName");
|
const industryName = getEnumHelper("IndustryType").nsGetMember(ctx, _industryName, "industryName");
|
||||||
return cloneDeep(IndustriesData[industryName]);
|
return structuredClone(IndustriesData[industryName]);
|
||||||
},
|
},
|
||||||
getMaterialData: (ctx) => (_materialName) => {
|
getMaterialData: (ctx) => (_materialName) => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
|
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
|
||||||
return cloneDeep(MaterialInfo[materialName]);
|
return structuredClone(MaterialInfo[materialName]);
|
||||||
},
|
},
|
||||||
expandIndustry: (ctx) => (_industryName, _divisionName) => {
|
expandIndustry: (ctx) => (_industryName, _divisionName) => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import type { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
import { Infiltration as NetscriptInfiltation, InfiltrationLocation } from "@nsdefs";
|
import { Infiltration as NetscriptInfiltation, InfiltrationLocation, ILocation } from "@nsdefs";
|
||||||
import { FactionName, LocationName } from "@enums";
|
import { FactionName, LocationName } from "@enums";
|
||||||
import { Location } from "../Locations/Location";
|
import { Location } from "../Locations/Location";
|
||||||
import { Locations } from "../Locations/Locations";
|
import { Locations } from "../Locations/Locations";
|
||||||
@ -29,7 +29,7 @@ export function NetscriptInfiltration(): InternalAPI<NetscriptInfiltation> {
|
|||||||
const reward = calculateReward(startingSecurityLevel);
|
const reward = calculateReward(startingSecurityLevel);
|
||||||
const maxLevel = location.infiltrationData.maxClearanceLevel;
|
const maxLevel = location.infiltrationData.maxClearanceLevel;
|
||||||
return {
|
return {
|
||||||
location: JSON.parse(JSON.stringify(location)),
|
location: structuredClone(location) as ILocation,
|
||||||
reward: {
|
reward: {
|
||||||
tradeRep: calculateTradeInformationRepReward(reward, maxLevel, startingSecurityLevel),
|
tradeRep: calculateTradeInformationRepReward(reward, maxLevel, startingSecurityLevel),
|
||||||
sellCash: calculateSellInformationCashReward(reward, maxLevel, startingSecurityLevel),
|
sellCash: calculateSellInformationCashReward(reward, maxLevel, startingSecurityLevel),
|
||||||
|
@ -10,7 +10,6 @@ import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBlad
|
|||||||
import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork";
|
import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork";
|
||||||
import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork";
|
import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork";
|
||||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
import { cloneDeep } from "lodash";
|
|
||||||
import { getAugCost } from "../Augmentation/AugmentationHelpers";
|
import { getAugCost } from "../Augmentation/AugmentationHelpers";
|
||||||
import { Factions } from "../Faction/Factions";
|
import { Factions } from "../Faction/Factions";
|
||||||
|
|
||||||
@ -161,10 +160,10 @@ export function NetscriptSleeve(): InternalAPI<NetscriptSleeve> {
|
|||||||
const sl = Player.sleeves[sleeveNumber];
|
const sl = Player.sleeves[sleeveNumber];
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
hp: cloneDeep(sl.hp),
|
hp: structuredClone(sl.hp),
|
||||||
skills: cloneDeep(sl.skills),
|
skills: structuredClone(sl.skills),
|
||||||
exp: cloneDeep(sl.exp),
|
exp: structuredClone(sl.exp),
|
||||||
mults: cloneDeep(sl.mults),
|
mults: structuredClone(sl.mults),
|
||||||
city: sl.city,
|
city: sl.city,
|
||||||
shock: sl.shock,
|
shock: sl.shock,
|
||||||
sync: sl.sync,
|
sync: sl.sync,
|
||||||
|
@ -20,7 +20,6 @@ import { Stock } from "../StockMarket/Stock";
|
|||||||
import { StockOrder, TIX } from "@nsdefs";
|
import { StockOrder, TIX } from "@nsdefs";
|
||||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
import { cloneDeep } from "lodash";
|
|
||||||
import { StockMarketConstants } from "../StockMarket/data/Constants";
|
import { StockMarketConstants } from "../StockMarket/data/Constants";
|
||||||
|
|
||||||
export function NetscriptStockMarket(): InternalAPI<TIX> {
|
export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||||
@ -44,7 +43,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getConstants: () => () => cloneDeep(StockMarketConstants),
|
getConstants: () => () => structuredClone(StockMarketConstants),
|
||||||
hasWSEAccount: () => () => Player.hasWseAccount,
|
hasWSEAccount: () => () => Player.hasWseAccount,
|
||||||
hasTIXAPIAccess: () => () => Player.hasTixApiAccess,
|
hasTIXAPIAccess: () => () => Player.hasTixApiAccess,
|
||||||
has4SData: () => () => Player.has4SData,
|
has4SData: () => () => Player.has4SData,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import type { editor } from "monaco-editor";
|
import type { editor } from "monaco-editor";
|
||||||
import { getRecordKeys } from "../../Types/Record";
|
import { getRecordKeys } from "../../Types/Record";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { cloneDeep } from "lodash";
|
|
||||||
type DefineThemeFn = typeof editor.defineTheme;
|
type DefineThemeFn = typeof editor.defineTheme;
|
||||||
|
|
||||||
export interface IScriptEditorTheme {
|
export interface IScriptEditorTheme {
|
||||||
@ -76,7 +75,7 @@ const colorRegExp = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/;
|
|||||||
// Invalid data will be replaced with FF0000 (bright red)
|
// Invalid data will be replaced with FF0000 (bright red)
|
||||||
export const sanitizeTheme = (theme: IScriptEditorTheme): void => {
|
export const sanitizeTheme = (theme: IScriptEditorTheme): void => {
|
||||||
if (typeof theme !== "object") {
|
if (typeof theme !== "object") {
|
||||||
Settings.EditorTheme = cloneDeep(defaultMonacoTheme);
|
Settings.EditorTheme = structuredClone(defaultMonacoTheme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const themeKey of getRecordKeys(theme)) {
|
for (const themeKey of getRecordKeys(theme)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user