@graffy/common
Version:
Common libraries that used by various Graffy modules.
137 lines (116 loc) • 3.76 kB
JavaScript
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import { encode as encodeValue, decode as decodeValue } from './struct.js';
import { keyStep, keyAfter, keyBefore } from '../ops/step.js';
import { throwIf, isEmpty, isArgObject } from '../util.js';
function joinEncode(value, prefix) {
if (!prefix && typeof value === 'string') {
return value;
} else {
return (prefix || '\0') + encodeValue(value);
}
}
export function encode(arg) {
if (!isArgObject(arg)) return {
key: joinEncode(arg, '')
};
var $first = arg.$first,
$last = arg.$last,
$after = arg.$after,
$before = arg.$before,
$since = arg.$since,
$until = arg.$until,
$cursor = arg.$cursor,
filter = _objectWithoutPropertiesLoose(arg, ["$first", "$last", "$after", "$before", "$since", "$until", "$cursor"]);
var hasRangeArg = $before || $after || $since || $until || $first || $last;
if (!hasRangeArg && !$cursor) return {
key: joinEncode(arg, '')
};
throwIf('first_and_$last', $first && $last);
throwIf('after_and_$since', $after && $since);
throwIf('before_and_$until', $before && $until);
throwIf('cursor_and_range_arg', $cursor && hasRangeArg);
var key, end;
var prefix = isEmpty(filter) ? '' : '\0' + encodeValue(filter) + '.';
if ($cursor) key = joinEncode($cursor, prefix);
if ($after) key = keyAfter(joinEncode($after, prefix));
if ($before) end = keyBefore(joinEncode($before, prefix));
if ($since) key = joinEncode($since, prefix);
if ($until) end = joinEncode($until, prefix);
if (hasRangeArg) {
key = key || prefix;
end = end || prefix + "\uFFFF";
}
if ($last) {
var _ref = [end, key];
key = _ref[0];
end = _ref[1];
}
var node = {
key: key
};
if (typeof end !== 'undefined') node.end = end;
if ($first || $last) node.limit = $first || $last;
return node;
}
/*
Key and End might take one of these forms:
filter.since .. filter.until
since .. until
filter.cursor
filter OR cursor (not distinguished)
*/
function splitEncoded(encodedKey) {
if (encodedKey[0] === '\0') {
var parts = encodedKey.slice(1).split('.');
var _slice = [undefined].concat(parts).slice(-2),
prefix = _slice[0],
cursor = _slice[1];
var _keyStep = keyStep(cursor),
key = _keyStep.key,
step = _keyStep.step;
var value = key === '' || key === "\uFFFF" ? key : decodeValue(key);
return {
prefix: prefix,
cursor: cursor,
value: value,
step: step
};
} else {
var _keyStep2 = keyStep(encodedKey),
_key = _keyStep2.key,
_step = _keyStep2.step;
return {
cursor: encodedKey,
value: _key,
step: _step
};
}
}
export function decode(node) {
if (typeof node === 'string') return node;
var key = node.key,
end = node.end,
limit = node.limit;
if (key[0] !== '\0' && typeof end === 'undefined') return key;
var args = {};
if (limit) args[key < end ? '$first' : '$last'] = limit;
var kParts = splitEncoded(key);
if (kParts.prefix) Object.assign(args, decodeValue(kParts.prefix));
if (typeof end === 'undefined') {
if (isEmpty(args)) return kParts.value;
args.$cursor = kParts.value;
return args;
}
var eParts = splitEncoded(end);
throwIf('prefix_mismatch', eParts.prefix !== kParts.prefix);
var _ref2 = eParts.cursor > kParts.cursor ? [kParts, eParts] : [eParts, kParts],
lower = _ref2[0],
upper = _ref2[1];
if (lower.cursor !== '') {
args[lower.step === 1 ? '$after' : '$since'] = lower.value;
}
if (upper.cursor !== "\uFFFF") {
args[upper.step === -1 ? '$before' : '$until'] = upper.value;
}
return args;
}