UNPKG

@salesforce/core

Version:

Core libraries to interact with SFDX projects, orgs, and APIs.

89 lines 3.9 kB
"use strict"; /* * Copyright (c) 2023, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ Object.defineProperty(exports, "__esModule", { value: true }); exports.LWWMap = exports.stateFromContents = exports.SYMBOL_FOR_DELETED = void 0; const ts_types_1 = require("@salesforce/ts-types"); const time_1 = require("../util/time"); const lwwRegister_1 = require("./lwwRegister"); exports.SYMBOL_FOR_DELETED = 'UNIQUE_IDENTIFIER_FOR_DELETED'; /** * @param contents object aligning with ConfigContents * @param timestamp a bigInt that sets the timestamp. Defaults to the current time * construct a LWWState from an object * @param keysToCheckForDeletion if a key is in this array, AND not in the contents, it will be marked as deleted * */ const stateFromContents = (contents, timestamp) => Object.fromEntries((0, ts_types_1.entriesOf)(contents).map(([key, value]) => [ key, new lwwRegister_1.LWWRegister({ timestamp: timestamp ?? (0, time_1.nowBigInt)(), value }), ]) // I'd love to get rid of this ASsertion but don't know how. ); exports.stateFromContents = stateFromContents; class LWWMap { /** map of key to LWWRegister. Used for managing conflicts */ #data = new Map(); constructor(state) { // create a new register for each key in the initial state for (const [key, register] of (0, ts_types_1.entriesOf)(state ?? {})) { this.#data.set(key, new lwwRegister_1.LWWRegister(register)); } } get value() { return Object.fromEntries(Array.from(this.#data.entries()) .filter(([, register]) => register.value !== exports.SYMBOL_FOR_DELETED) .map(([key, register]) => [key, register.value])); } get state() { return Object.fromEntries(Array.from(this.#data.entries()).map(([key, register]) => [key, register.state])); } // Merge top-level properties of the incoming state with the current state. // The value with the latest timestamp wins. merge(state) { // properties that are in the incoming state but not the current state might have been deleted. // recursively merge each key's register with the incoming state for that key for (const [key, remote] of (0, ts_types_1.entriesOf)(state)) { const local = this.#data.get(key); // if the register already exists, merge it with the incoming state if (local) local.merge(remote); // otherwise, instantiate a new `LWWRegister` with the incoming state else this.#data.set(key, new lwwRegister_1.LWWRegister(remote)); } return this.state; } set(key, value) { // get the register at the given key const register = this.#data.get(key); // if the register already exists, set the value if (register) register.set(value); // otherwise, instantiate a new `LWWRegister` with the value else this.#data.set(key, new lwwRegister_1.LWWRegister({ timestamp: (0, time_1.nowBigInt)(), value })); } get(key) { // map loses the typing const value = this.#data.get(key)?.value; if (value === exports.SYMBOL_FOR_DELETED) return undefined; return value; } delete(key) { this.#data.set(key, new lwwRegister_1.LWWRegister({ timestamp: (0, time_1.nowBigInt)(), value: exports.SYMBOL_FOR_DELETED, })); } has(key) { // if a register doesn't exist or its value is null, the map doesn't contain the key return this.#data.has(key) && this.#data.get(key)?.value !== exports.SYMBOL_FOR_DELETED; } } exports.LWWMap = LWWMap; //# sourceMappingURL=lwwMap.js.map