signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
157 lines (155 loc) • 5.55 kB
JavaScript
"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;