feat: complete Ancestor quote bot with production-ready Docker support
This commit is contained in:
277
node_modules/matrix-js-sdk/lib/utils.js
generated
vendored
277
node_modules/matrix-js-sdk/lib/utils.js
generated
vendored
@@ -1,28 +1,75 @@
|
||||
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
|
||||
/*
|
||||
Copyright 2015, 2016, 2019, 2023 The Matrix.org Foundation C.I.C.
|
||||
"use strict";
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is an internal module.
|
||||
*/
|
||||
|
||||
import unhomoglyph from "unhomoglyph";
|
||||
import promiseRetry from "p-retry";
|
||||
import { M_TIMESTAMP } from "./@types/location.js";
|
||||
import { ReceiptType } from "./@types/read_receipts.js";
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.MapWithDefault = exports.DEFAULT_ALPHABET = void 0;
|
||||
exports.alphabetPad = alphabetPad;
|
||||
exports.averageBetweenStrings = averageBetweenStrings;
|
||||
exports.baseToString = baseToString;
|
||||
exports.checkObjectHasKeys = checkObjectHasKeys;
|
||||
exports.chunkPromises = chunkPromises;
|
||||
exports.compare = compare;
|
||||
exports.decodeParams = decodeParams;
|
||||
exports.deepCompare = deepCompare;
|
||||
exports.deepCopy = deepCopy;
|
||||
exports.deepSortedObjectEntries = deepSortedObjectEntries;
|
||||
exports.defer = defer;
|
||||
exports.encodeParams = encodeParams;
|
||||
exports.encodeUri = encodeUri;
|
||||
exports.ensureNoTrailingSlash = ensureNoTrailingSlash;
|
||||
exports.escapeRegExp = escapeRegExp;
|
||||
exports.globToRegexp = globToRegexp;
|
||||
exports.immediate = immediate;
|
||||
exports.internaliseString = internaliseString;
|
||||
exports.isFunction = isFunction;
|
||||
exports.isNullOrUndefined = isNullOrUndefined;
|
||||
exports.isNumber = isNumber;
|
||||
exports.isSupportedReceiptType = isSupportedReceiptType;
|
||||
exports.lexicographicCompare = lexicographicCompare;
|
||||
exports.mapsEqual = mapsEqual;
|
||||
exports.nextString = nextString;
|
||||
exports.noUnsafeEventProps = noUnsafeEventProps;
|
||||
exports.normalize = normalize;
|
||||
exports.prevString = prevString;
|
||||
exports.promiseMapSeries = promiseMapSeries;
|
||||
exports.promiseTry = promiseTry;
|
||||
exports.recursiveMapToObject = recursiveMapToObject;
|
||||
exports.recursivelyAssign = recursivelyAssign;
|
||||
exports.removeDirectionOverrideChars = removeDirectionOverrideChars;
|
||||
exports.removeElement = removeElement;
|
||||
exports.removeHiddenChars = removeHiddenChars;
|
||||
exports.replaceParam = replaceParam;
|
||||
exports.safeSet = safeSet;
|
||||
exports.simpleRetryOperation = simpleRetryOperation;
|
||||
exports.sleep = sleep;
|
||||
exports.sortEventsByLatestContentTimestamp = sortEventsByLatestContentTimestamp;
|
||||
exports.stringToBase = stringToBase;
|
||||
exports.unsafeProp = unsafeProp;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _unhomoglyph = _interopRequireDefault(require("unhomoglyph"));
|
||||
var _pRetry = _interopRequireDefault(require("p-retry"));
|
||||
var _location = require("./@types/location");
|
||||
var _read_receipts = require("./@types/read_receipts");
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /*
|
||||
Copyright 2015, 2016, 2019, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
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.
|
||||
*/ /**
|
||||
* This is an internal module.
|
||||
*/
|
||||
const interns = new Map();
|
||||
|
||||
/**
|
||||
@@ -31,10 +78,9 @@ const interns = new Map();
|
||||
* @param str - The string to internalise.
|
||||
* @returns The internalised string.
|
||||
*/
|
||||
export function internaliseString(str) {
|
||||
function internaliseString(str) {
|
||||
// Unwrap strings before entering the map, if we somehow got a wrapped
|
||||
// string as our input. This should only happen from tests.
|
||||
// oxlint-disable-next-line unicorn/no-instanceof-builtins
|
||||
if (str instanceof String) {
|
||||
str = str.toString();
|
||||
}
|
||||
@@ -55,8 +101,8 @@ export function internaliseString(str) {
|
||||
* `{"foo": "bar", "baz": "taz"}`
|
||||
* @returns The encoded string e.g. foo=bar&baz=taz
|
||||
*/
|
||||
export function encodeParams(params, urlSearchParams) {
|
||||
const searchParams = urlSearchParams ?? new URLSearchParams();
|
||||
function encodeParams(params, urlSearchParams) {
|
||||
const searchParams = urlSearchParams !== null && urlSearchParams !== void 0 ? urlSearchParams : new URLSearchParams();
|
||||
for (const [key, val] of Object.entries(params)) {
|
||||
if (val !== undefined && val !== null) {
|
||||
if (Array.isArray(val)) {
|
||||
@@ -73,7 +119,7 @@ export function encodeParams(params, urlSearchParams) {
|
||||
/**
|
||||
* Replace a stable parameter with the unstable naming for params
|
||||
*/
|
||||
export function replaceParam(stable, unstable, dict) {
|
||||
function replaceParam(stable, unstable, dict) {
|
||||
const result = _objectSpread(_objectSpread({}, dict), {}, {
|
||||
[unstable]: dict[stable]
|
||||
});
|
||||
@@ -90,7 +136,7 @@ export function replaceParam(stable, unstable, dict) {
|
||||
* This behaviour matches Node's qs.parse but is built on URLSearchParams
|
||||
* for native web compatibility
|
||||
*/
|
||||
export function decodeParams(query) {
|
||||
function decodeParams(query) {
|
||||
const o = {};
|
||||
const params = new URLSearchParams(query);
|
||||
for (const key of params.keys()) {
|
||||
@@ -108,7 +154,7 @@ export function decodeParams(query) {
|
||||
* variables with. E.g. `{ "$bar": "baz" }`.
|
||||
* @returns The result of replacing all template variables e.g. '/foo/baz'.
|
||||
*/
|
||||
export function encodeUri(pathTemplate, variables) {
|
||||
function encodeUri(pathTemplate, variables) {
|
||||
for (const key in variables) {
|
||||
if (!variables.hasOwnProperty(key)) {
|
||||
continue;
|
||||
@@ -132,7 +178,7 @@ export function encodeUri(pathTemplate, variables) {
|
||||
* @param reverse - True to search in reverse order.
|
||||
* @returns True if an element was removed.
|
||||
*/
|
||||
export function removeElement(array, fn, reverse) {
|
||||
function removeElement(array, fn, reverse) {
|
||||
let i;
|
||||
if (reverse) {
|
||||
for (i = array.length - 1; i >= 0; i--) {
|
||||
@@ -157,7 +203,7 @@ export function removeElement(array, fn, reverse) {
|
||||
* @param value - The thing to check.
|
||||
* @returns True if it is a function.
|
||||
*/
|
||||
export function isFunction(value) {
|
||||
function isFunction(value) {
|
||||
return Object.prototype.toString.call(value) === "[object Function]";
|
||||
}
|
||||
|
||||
@@ -168,7 +214,7 @@ export function isFunction(value) {
|
||||
* @throws If the object is missing keys.
|
||||
*/
|
||||
// note using 'keys' here would shadow the 'keys' function defined above
|
||||
export function checkObjectHasKeys(obj, keys) {
|
||||
function checkObjectHasKeys(obj, keys) {
|
||||
for (const key of keys) {
|
||||
if (!obj.hasOwnProperty(key)) {
|
||||
throw new Error("Missing required key: " + key);
|
||||
@@ -182,7 +228,7 @@ export function checkObjectHasKeys(obj, keys) {
|
||||
* @param obj - The object to deep copy.
|
||||
* @returns A copy of the object without any references to the original.
|
||||
*/
|
||||
export function deepCopy(obj) {
|
||||
function deepCopy(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
@@ -194,7 +240,7 @@ export function deepCopy(obj) {
|
||||
*
|
||||
* @returns true if the two objects are equal
|
||||
*/
|
||||
export function deepCompare(x, y) {
|
||||
function deepCompare(x, y) {
|
||||
// Inspired by
|
||||
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript#1144249
|
||||
|
||||
@@ -219,16 +265,12 @@ export function deepCompare(x, y) {
|
||||
}
|
||||
|
||||
// everything else is either an unequal primitive, or an object
|
||||
// XXX: this check has been temporarily tweaked due to issues in the jest test environment,
|
||||
// this will be reverted as part of the migration to vitest
|
||||
if (x.constructor.name !== "Object" && x.constructor.name !== "RegExp" && x.constructor.name !== "Date" && x.constructor.name !== "Array") {
|
||||
if (!(x instanceof Object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check they are the same type of object
|
||||
// XXX: this check has been temporarily tweaked due to issues in the jest test environment,
|
||||
// this will be reverted as part of the migration to vitest
|
||||
if (x.prototype !== y.prototype) {
|
||||
if (x.constructor !== y.constructor || x.prototype !== y.prototype) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -274,7 +316,7 @@ export function deepCompare(x, y) {
|
||||
* @param obj - The object to get entries of
|
||||
* @returns The entries, sorted by key.
|
||||
*/
|
||||
export function deepSortedObjectEntries(obj) {
|
||||
function deepSortedObjectEntries(obj) {
|
||||
if (typeof obj !== "object") return obj;
|
||||
|
||||
// Apparently these are object types...
|
||||
@@ -295,7 +337,7 @@ export function deepSortedObjectEntries(obj) {
|
||||
* @param value - the value to test
|
||||
* @returns whether or not value is a finite number without type-coercion
|
||||
*/
|
||||
export function isNumber(value) {
|
||||
function isNumber(value) {
|
||||
return typeof value === "number" && isFinite(value);
|
||||
}
|
||||
|
||||
@@ -305,9 +347,9 @@ export function isNumber(value) {
|
||||
* @param str - the string to remove hidden characters from
|
||||
* @returns a string with the hidden characters removed
|
||||
*/
|
||||
export function removeHiddenChars(str) {
|
||||
function removeHiddenChars(str) {
|
||||
if (typeof str === "string") {
|
||||
return unhomoglyph(str.normalize("NFD").replace(removeHiddenCharsRegex, ""));
|
||||
return (0, _unhomoglyph.default)(str.normalize("NFD").replace(removeHiddenCharsRegex, ""));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -316,13 +358,13 @@ export function removeHiddenChars(str) {
|
||||
* Removes the direction override characters from a string
|
||||
* @returns string with chars removed
|
||||
*/
|
||||
export function removeDirectionOverrideChars(str) {
|
||||
function removeDirectionOverrideChars(str) {
|
||||
if (typeof str === "string") {
|
||||
return str.replace(/[\u202d-\u202e]/g, "");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
export function normalize(str) {
|
||||
function normalize(str) {
|
||||
// Note: we have to match the filter with the removeHiddenChars() because the
|
||||
// function strips spaces and other characters (M becomes RN for example, in lowercase).
|
||||
return removeHiddenChars(str.toLowerCase())
|
||||
@@ -343,7 +385,7 @@ export function normalize(str) {
|
||||
// Blank/invisible characters (U2800, U2062-U2063)
|
||||
// eslint-disable-next-line no-misleading-character-class
|
||||
const removeHiddenCharsRegex = /[\u2000-\u200F\u202A-\u202F\u0300-\u036F\uFEFF\u061C\u2800\u2062-\u2063\s]/g;
|
||||
export function escapeRegExp(string) {
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
@@ -353,11 +395,11 @@ export function escapeRegExp(string) {
|
||||
* @param glob - Matrix glob-style string
|
||||
* @returns regular expression
|
||||
*/
|
||||
export function globToRegexp(glob) {
|
||||
function globToRegexp(glob) {
|
||||
return escapeRegExp(glob).replace(/\\\*/g, ".*").replace(/\?/g, ".");
|
||||
}
|
||||
export function ensureNoTrailingSlash(url) {
|
||||
if (url?.endsWith("/")) {
|
||||
function ensureNoTrailingSlash(url) {
|
||||
if (url !== null && url !== void 0 && url.endsWith("/")) {
|
||||
return url.slice(0, -1);
|
||||
} else {
|
||||
return url;
|
||||
@@ -367,70 +409,47 @@ export function ensureNoTrailingSlash(url) {
|
||||
/**
|
||||
* Returns a promise which resolves with a given value after the given number of ms
|
||||
*/
|
||||
export function sleep(ms, value) {
|
||||
function sleep(ms, value) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, ms, value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to log the duration of a promise.
|
||||
*
|
||||
* @param logger - The logger to log to.
|
||||
* @param name - The name of the operation.
|
||||
* @param block - The block to execute.
|
||||
*/
|
||||
export async function logDuration(logger, name, block) {
|
||||
const start = Date.now();
|
||||
try {
|
||||
return await block();
|
||||
} finally {
|
||||
const end = Date.now();
|
||||
logger.debug(`[Perf]: ${name} took ${end - start}ms`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to log the duration of a synchronous block.
|
||||
*
|
||||
* @param logger - The logger to log to.
|
||||
* @param name - The name of the operation.
|
||||
* @param block - The block to execute.
|
||||
*/
|
||||
export function logDurationSync(logger, name, block) {
|
||||
const start = Date.now();
|
||||
try {
|
||||
return block();
|
||||
} finally {
|
||||
const end = Date.now();
|
||||
logger.debug(`[Perf]: ${name} took ${end - start}ms`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Promise/async version of {@link setImmediate}.
|
||||
*
|
||||
* Implementation is based on `setTimeout` for wider compatibility.
|
||||
* @deprecated Use {@link sleep} instead.
|
||||
*/
|
||||
export function immediate() {
|
||||
return new Promise(resolve => setTimeout(resolve));
|
||||
function immediate() {
|
||||
return new Promise(setImmediate);
|
||||
}
|
||||
export function isNullOrUndefined(val) {
|
||||
function isNullOrUndefined(val) {
|
||||
return val === null || val === undefined;
|
||||
}
|
||||
export async function promiseMapSeries(promises, fn // if async we don't care about the type as we only await resolution
|
||||
// Returns a Deferred
|
||||
function defer() {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((_resolve, _reject) => {
|
||||
resolve = _resolve;
|
||||
reject = _reject;
|
||||
});
|
||||
return {
|
||||
resolve,
|
||||
reject,
|
||||
promise
|
||||
};
|
||||
}
|
||||
async function promiseMapSeries(promises, fn // if async we don't care about the type as we only await resolution
|
||||
) {
|
||||
for (const o of promises) {
|
||||
await fn(await o);
|
||||
}
|
||||
}
|
||||
export function promiseTry(fn) {
|
||||
function promiseTry(fn) {
|
||||
return Promise.resolve(fn());
|
||||
}
|
||||
|
||||
// Creates and awaits all promises, running no more than `chunkSize` at the same time
|
||||
export async function chunkPromises(fns, chunkSize) {
|
||||
async function chunkPromises(fns, chunkSize) {
|
||||
const results = [];
|
||||
for (let i = 0; i < fns.length; i += chunkSize) {
|
||||
results.push(...(await Promise.all(fns.slice(i, i + chunkSize).map(fn => fn()))));
|
||||
@@ -445,18 +464,13 @@ export async function chunkPromises(fns, chunkSize) {
|
||||
* should always return a new promise.
|
||||
* @param promiseFn - The function to call to get a fresh promise instance. Takes an
|
||||
* attempt count as an argument, for logging/debugging purposes.
|
||||
* @param shouldRetry - Optional function which is called with the error the latest rejection from promiseFn,
|
||||
* retrying will ba aborted if this return false.
|
||||
* @returns The promise for the retried operation.
|
||||
*/
|
||||
export function simpleRetryOperation(promiseFn, shouldRetry) {
|
||||
return promiseRetry(attempt => {
|
||||
function simpleRetryOperation(promiseFn) {
|
||||
return (0, _pRetry.default)(attempt => {
|
||||
return promiseFn(attempt);
|
||||
}, {
|
||||
retries: Infinity,
|
||||
shouldRetry: shouldRetry ? ({
|
||||
error
|
||||
}) => shouldRetry(error) : undefined,
|
||||
forever: true,
|
||||
factor: 2,
|
||||
minTimeout: 3000,
|
||||
// ms
|
||||
@@ -473,7 +487,7 @@ export function simpleRetryOperation(promiseFn, shouldRetry) {
|
||||
* The default alphabet used by string averaging in this SDK. This matches
|
||||
* all usefully printable ASCII characters (0x20-0x7E, inclusive).
|
||||
*/
|
||||
export const DEFAULT_ALPHABET = (() => {
|
||||
const DEFAULT_ALPHABET = (() => {
|
||||
let str = "";
|
||||
for (let c = 0x20; c <= 0x7e; c++) {
|
||||
str += String.fromCharCode(c);
|
||||
@@ -491,7 +505,8 @@ export const DEFAULT_ALPHABET = (() => {
|
||||
* @param alphabet - The alphabet to use as a single string.
|
||||
* @returns The padded string.
|
||||
*/
|
||||
export function alphabetPad(s, n, alphabet = DEFAULT_ALPHABET) {
|
||||
exports.DEFAULT_ALPHABET = DEFAULT_ALPHABET;
|
||||
function alphabetPad(s, n, alphabet = DEFAULT_ALPHABET) {
|
||||
return s.padEnd(n, alphabet[0]);
|
||||
}
|
||||
|
||||
@@ -503,7 +518,7 @@ export function alphabetPad(s, n, alphabet = DEFAULT_ALPHABET) {
|
||||
* @param alphabet - The alphabet to use as a single string.
|
||||
* @returns The baseN number encoded as a string from the alphabet.
|
||||
*/
|
||||
export function baseToString(n, alphabet = DEFAULT_ALPHABET) {
|
||||
function baseToString(n, alphabet = DEFAULT_ALPHABET) {
|
||||
// Developer note: the stringToBase() function offsets the character set by 1 so that repeated
|
||||
// characters (ie: "aaaaaa" in a..z) don't come out as zero. We have to reverse this here as
|
||||
// otherwise we'll be wrong in our conversion. Undoing a +1 before an exponent isn't very fun
|
||||
@@ -512,7 +527,8 @@ export function baseToString(n, alphabet = DEFAULT_ALPHABET) {
|
||||
|
||||
const len = BigInt(alphabet.length);
|
||||
if (n <= len) {
|
||||
return alphabet[Number(n) - 1] ?? "";
|
||||
var _alphabet;
|
||||
return (_alphabet = alphabet[Number(n) - 1]) !== null && _alphabet !== void 0 ? _alphabet : "";
|
||||
}
|
||||
let d = n / len;
|
||||
let r = Number(n % len) - 1;
|
||||
@@ -535,7 +551,7 @@ export function baseToString(n, alphabet = DEFAULT_ALPHABET) {
|
||||
* @param alphabet - The alphabet to use as a single string.
|
||||
* @returns The baseN number.
|
||||
*/
|
||||
export function stringToBase(s, alphabet = DEFAULT_ALPHABET) {
|
||||
function stringToBase(s, alphabet = DEFAULT_ALPHABET) {
|
||||
const len = BigInt(alphabet.length);
|
||||
|
||||
// In our conversion to baseN we do a couple performance optimizations to avoid using
|
||||
@@ -570,7 +586,7 @@ export function stringToBase(s, alphabet = DEFAULT_ALPHABET) {
|
||||
* @param alphabet - The alphabet to use as a single string.
|
||||
* @returns The midpoint between the strings, as a string.
|
||||
*/
|
||||
export function averageBetweenStrings(a, b, alphabet = DEFAULT_ALPHABET) {
|
||||
function averageBetweenStrings(a, b, alphabet = DEFAULT_ALPHABET) {
|
||||
const padN = Math.max(a.length, b.length);
|
||||
const baseA = stringToBase(alphabetPad(a, padN, alphabet), alphabet);
|
||||
const baseB = stringToBase(alphabetPad(b, padN, alphabet), alphabet);
|
||||
@@ -592,7 +608,7 @@ export function averageBetweenStrings(a, b, alphabet = DEFAULT_ALPHABET) {
|
||||
* @param alphabet - The alphabet to use as a single string.
|
||||
* @returns The string which follows the input string.
|
||||
*/
|
||||
export function nextString(s, alphabet = DEFAULT_ALPHABET) {
|
||||
function nextString(s, alphabet = DEFAULT_ALPHABET) {
|
||||
return baseToString(stringToBase(s, alphabet) + BigInt(1), alphabet);
|
||||
}
|
||||
|
||||
@@ -604,7 +620,7 @@ export function nextString(s, alphabet = DEFAULT_ALPHABET) {
|
||||
* @param alphabet - The alphabet to use as a single string.
|
||||
* @returns The string which precedes the input string.
|
||||
*/
|
||||
export function prevString(s, alphabet = DEFAULT_ALPHABET) {
|
||||
function prevString(s, alphabet = DEFAULT_ALPHABET) {
|
||||
return baseToString(stringToBase(s, alphabet) - BigInt(1), alphabet);
|
||||
}
|
||||
|
||||
@@ -615,7 +631,7 @@ export function prevString(s, alphabet = DEFAULT_ALPHABET) {
|
||||
* @returns Negative if the reference string is before the compare string;
|
||||
* positive if the reference string is after; and zero if equal.
|
||||
*/
|
||||
export function lexicographicCompare(a, b) {
|
||||
function lexicographicCompare(a, b) {
|
||||
// Dev note: this exists because I'm sad that you can use math operators on strings, so I've
|
||||
// hidden the operation in this function.
|
||||
if (a < b) {
|
||||
@@ -626,6 +642,15 @@ export function lexicographicCompare(a, b) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
const collator = new Intl.Collator();
|
||||
/**
|
||||
* Performant language-sensitive string comparison
|
||||
* @param a - the first string to compare
|
||||
* @param b - the second string to compare
|
||||
*/
|
||||
function compare(a, b) {
|
||||
return collator.compare(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is similar to Object.assign() but it assigns recursively and
|
||||
@@ -633,7 +658,7 @@ export function lexicographicCompare(a, b) {
|
||||
*
|
||||
* @returns the target object
|
||||
*/
|
||||
export function recursivelyAssign(target, source, ignoreNullish = false) {
|
||||
function recursivelyAssign(target, source, ignoreNullish = false) {
|
||||
for (const [sourceKey, sourceValue] of Object.entries(source)) {
|
||||
if (target[sourceKey] instanceof Object && sourceValue) {
|
||||
recursivelyAssign(target[sourceKey], sourceValue);
|
||||
@@ -647,25 +672,26 @@ export function recursivelyAssign(target, source, ignoreNullish = false) {
|
||||
return target;
|
||||
}
|
||||
function getContentTimestampWithFallback(event) {
|
||||
return M_TIMESTAMP.findIn(event.getContent()) ?? -1;
|
||||
var _M_TIMESTAMP$findIn;
|
||||
return (_M_TIMESTAMP$findIn = _location.M_TIMESTAMP.findIn(event.getContent())) !== null && _M_TIMESTAMP$findIn !== void 0 ? _M_TIMESTAMP$findIn : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort events by their content m.ts property
|
||||
* Latest timestamp first
|
||||
*/
|
||||
export function sortEventsByLatestContentTimestamp(left, right) {
|
||||
function sortEventsByLatestContentTimestamp(left, right) {
|
||||
return getContentTimestampWithFallback(right) - getContentTimestampWithFallback(left);
|
||||
}
|
||||
export function isSupportedReceiptType(receiptType) {
|
||||
return [ReceiptType.Read, ReceiptType.ReadPrivate].includes(receiptType);
|
||||
function isSupportedReceiptType(receiptType) {
|
||||
return [_read_receipts.ReceiptType.Read, _read_receipts.ReceiptType.ReadPrivate].includes(receiptType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether two maps are equal.
|
||||
* @param eq - The equivalence relation to compare values by. Defaults to strict equality.
|
||||
*/
|
||||
export function mapsEqual(x, y, eq = (v1, v2) => v1 === v2) {
|
||||
function mapsEqual(x, y, eq = (v1, v2) => v1 === v2) {
|
||||
if (x.size !== y.size) return false;
|
||||
for (const [k, v1] of x) {
|
||||
const v2 = y.get(k);
|
||||
@@ -689,26 +715,26 @@ function processMapToObjectValue(value) {
|
||||
* Recursively converts Maps to plain objects.
|
||||
* Also supports sub-lists of Maps.
|
||||
*/
|
||||
export function recursiveMapToObject(map) {
|
||||
function recursiveMapToObject(map) {
|
||||
const targetMap = new Map();
|
||||
for (const [key, value] of map) {
|
||||
targetMap.set(key, processMapToObjectValue(value));
|
||||
}
|
||||
return Object.fromEntries(targetMap.entries());
|
||||
}
|
||||
export function unsafeProp(prop) {
|
||||
function unsafeProp(prop) {
|
||||
return prop === "__proto__" || prop === "prototype" || prop === "constructor";
|
||||
}
|
||||
export function safeSet(obj, prop, value) {
|
||||
function safeSet(obj, prop, value) {
|
||||
if (unsafeProp(prop)) {
|
||||
throw new Error("Trying to modify prototype or constructor");
|
||||
}
|
||||
obj[prop] = value;
|
||||
}
|
||||
export function noUnsafeEventProps(event) {
|
||||
return !(unsafeProp(event.room_id) || unsafeProp(event.sender) || unsafeProp(event.event_id));
|
||||
function noUnsafeEventProps(event) {
|
||||
return !(unsafeProp(event.room_id) || unsafeProp(event.sender) || unsafeProp(event.user_id) || unsafeProp(event.event_id));
|
||||
}
|
||||
export class MapWithDefault extends Map {
|
||||
class MapWithDefault extends Map {
|
||||
constructor(createDefault) {
|
||||
super();
|
||||
this.createDefault = createDefault;
|
||||
@@ -725,4 +751,5 @@ export class MapWithDefault extends Map {
|
||||
return this.get(key);
|
||||
}
|
||||
}
|
||||
exports.MapWithDefault = MapWithDefault;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
Reference in New Issue
Block a user