UNPKG

signalk-server

Version:

An implementation of a [Signal K](http://signalk.org) server for boats.

157 lines (155 loc) 5.55 kB
"use strict"; /* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright 2020 Scott Bender <scott@scottbender.net> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const fs_1 = __importDefault(require("fs")); const lodash_1 = __importDefault(require("lodash")); const VALUES = 'values'; const META = 'meta'; const SELF_VESSEL = 'vessels.self'; class DeltaEditor { deltas; constructor() { this.deltas = []; } load(filename) { const data = fs_1.default.readFileSync(filename, 'utf8'); const deltas = JSON.parse(data); if (!lodash_1.default.isArray(deltas)) { throw new Error(`${filename} should contain an array of deltas`); } this.deltas = deltas; } saveSync(filename) { fs_1.default.writeFileSync(filename, JSON.stringify(this.deltas, null, 2)); } save(filename) { return fs_1.default.promises.writeFile(filename, JSON.stringify(this.deltas, null, 2)); } setValue(context, path, value) { if (lodash_1.default.isUndefined(value)) { return this.removeValue(context, path); } if (path.indexOf('.') === -1) { const deltaInfo = getDelta(this.deltas, context, '', VALUES); const newVal = deltaInfo && deltaInfo.kp ? deltaInfo.kp.value : {}; newVal[path] = value; return setDelta(this.deltas, context, '', newVal, VALUES); } else { return setDelta(this.deltas, context, path, value, VALUES); } } setSelfValue(path, value) { return this.setValue(SELF_VESSEL, path, value); } setMeta(context, path, value) { return setDelta(this.deltas, context, path, value, META); } getValue(context, path) { if (path.indexOf('.') === -1) { const deltaInfo = getDelta(this.deltas, context, '', VALUES); return deltaInfo && deltaInfo.kp && deltaInfo.kp.value[path]; } else { const deltaInfo = getDelta(this.deltas, context, path, VALUES); return deltaInfo && deltaInfo.kp && deltaInfo.kp.value; } } getSelfValue(path) { return this.getValue(SELF_VESSEL, path); } getMeta(context, path) { const deltaInfo = getDelta(this.deltas, context, path, META); return deltaInfo && deltaInfo.kp && deltaInfo.kp.value; } removeValue(context, path) { if (path.indexOf('.') === -1) { const deltaInfo = getDelta(this.deltas, context, '', VALUES); if (deltaInfo && deltaInfo.kp) { delete deltaInfo.kp.value[path]; if (lodash_1.default.keys(deltaInfo.kp.value).length === 0) { lodash_1.default.pull(this.deltas, deltaInfo.delta); } } } else { const deltaInfo = getDelta(this.deltas, context, path, VALUES); if (deltaInfo && deltaInfo.kp) { lodash_1.default.pull(deltaInfo.delta.updates[0].values, deltaInfo.kp); if (deltaInfo.delta.updates[0].values.length === 0) { lodash_1.default.pull(this.deltas, deltaInfo.delta); } } } } removeSelfValue(path) { return this.removeValue(SELF_VESSEL, path); } removeMeta(context, path) { const deltaInfo = getDelta(this.deltas, context, path, META); if (deltaInfo && deltaInfo.kp) { lodash_1.default.pull(deltaInfo.delta.updates[0].meta, deltaInfo.kp); if (deltaInfo.delta.updates[0].meta.length === 0) { lodash_1.default.pull(this.deltas, deltaInfo.delta); } } } } function setDelta(deltas, context, path, value, type) { const deltaInfo = getDelta(deltas, context, path, type); if (deltaInfo && deltaInfo.kp) { deltaInfo.kp.value = value; return deltaInfo.delta; } else if (deltaInfo) { deltaInfo.delta.updates[0][type].push({ path, value }); return deltaInfo.delta; } else { const delta = { context, updates: [ { [type]: [ { path, value } ] } ] }; deltas.push(delta); return delta; } } function getDelta(deltas, context, path, type) { for (const delta of deltas) { if (delta.updates && delta.context === context) { for (const update of delta.updates) { if (update[type]) { const foundKp = update[type].find((kp) => kp.path === path); return { delta, kp: foundKp }; } } } } return null; } module.exports = DeltaEditor;