@player-ui/player
Version:
1,783 lines (1,763 loc) • 170 kB
JavaScript
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/index.ts
export * from "@player-ui/types";
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding/index.ts
import { SyncBailHook, SyncWaterfallHook } from "tapable-ts";
import { NestedError as NestedError2 } from "ts-nested-error";
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding-grammar/ast.ts
var toValue = (value) => ({
name: "Value",
value
});
var toExpression = (value) => ({
name: "Expression",
value
});
var toPath = (path) => ({
name: "PathNode",
path
});
var toQuery = (key, value) => ({
name: "Query",
key,
value
});
var toConcatenatedNode = (values) => {
if (values.length === 1) {
return values[0];
}
return {
name: "Concatenated",
value: values
};
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding-grammar/custom/index.ts
var SEGMENT_SEPARATOR = ".";
var OPEN_CURL = "{";
var CLOSE_CURL = "}";
var OPEN_BRACKET = "[";
var CLOSE_BRACKET = "]";
var EQUALS = "=";
var SINGLE_QUOTE = "'";
var DOUBLE_QUOTE = '"';
var BACK_TICK = "`";
var isIdentifierChar = (char) => {
if (!char) {
return false;
}
const charCode = char.charCodeAt(0);
const matches = charCode === 32 || // ' '
charCode === 34 || // "
charCode === 39 || // '
charCode === 40 || // (
charCode === 41 || // )
charCode === 42 || // *
charCode === 46 || // .
charCode === 61 || // =
charCode === 91 || // [
charCode === 93 || // ]
charCode === 96 || // `
charCode === 123 || // {
charCode === 125;
return !matches;
};
var parse = (path) => {
let index = 1;
let ch = path.charAt(0);
const next = (expected) => {
if (expected && ch !== expected) {
throw new Error(`Expected char: ${expected} but got: ${ch}`);
}
ch = path.charAt(index);
index += 1;
return ch;
};
const whitespace = () => {
while (ch === " ") {
next();
}
};
const identifier = () => {
if (!isIdentifierChar(ch)) {
return;
}
let value = ch;
while (next()) {
if (!isIdentifierChar(ch)) {
break;
}
value += ch;
}
if (value) {
const maybeNumber = Number(value);
value = isNaN(maybeNumber) ? value : maybeNumber;
return toValue(value);
}
};
const expression = () => {
if (ch === BACK_TICK) {
next(BACK_TICK);
let exp = ch;
while (next()) {
if (ch === BACK_TICK) {
break;
}
exp += ch;
}
next(BACK_TICK);
if (exp) {
return toExpression(exp);
}
}
};
const regex = (match) => {
if (!ch?.match(match)) {
return;
}
let value = ch;
while (next()) {
if (!ch?.match(match)) {
break;
}
value += ch;
}
if (value) {
return toValue(value);
}
};
const nestedPath = () => {
if (ch === OPEN_CURL) {
next(OPEN_CURL);
next(OPEN_CURL);
const modelRef = parsePath();
next(CLOSE_CURL);
next(CLOSE_CURL);
return modelRef;
}
};
const simpleSegment = () => nestedPath() ?? expression() ?? identifier();
const segment = () => {
const segments = [];
let nextSegment = simpleSegment();
while (nextSegment !== void 0) {
segments.push(nextSegment);
nextSegment = simpleSegment();
}
if (segments.length === 0) {
return void 0;
}
return toConcatenatedNode(segments);
};
const optionallyQuotedSegment = () => {
whitespace();
if (ch === SINGLE_QUOTE || ch === DOUBLE_QUOTE) {
const singleQuote = ch === SINGLE_QUOTE;
next(singleQuote ? SINGLE_QUOTE : DOUBLE_QUOTE);
const id = regex(/[^'"]+/);
next(singleQuote ? SINGLE_QUOTE : DOUBLE_QUOTE);
return id;
}
return simpleSegment();
};
const equals = () => {
if (ch !== EQUALS) {
return false;
}
while (ch === EQUALS) {
next();
}
return true;
};
const parseBracket = () => {
if (ch === OPEN_BRACKET) {
next(OPEN_BRACKET);
whitespace();
let value = optionallyQuotedSegment();
if (value) {
whitespace();
if (equals()) {
whitespace();
const second = optionallyQuotedSegment();
value = toQuery(value, second);
whitespace();
}
} else {
throw new Error(`Expected identifier`);
}
if (value) {
next(CLOSE_BRACKET);
}
return value;
}
};
const parseSegmentAndBrackets = () => {
const parsed = [];
const firstSegment = segment();
if (firstSegment) {
parsed.push(firstSegment);
let bracketSegment = parseBracket();
if (bracketSegment?.name === "Value") {
const maybeNumber = Number(bracketSegment.value);
bracketSegment.value = isNaN(maybeNumber) || String(maybeNumber) !== bracketSegment.value ? bracketSegment.value : maybeNumber;
}
while (bracketSegment !== void 0) {
parsed.push(bracketSegment);
bracketSegment = parseBracket();
}
}
return parsed;
};
const parsePath = () => {
const parts = [];
let nextSegment = parseSegmentAndBrackets();
while (nextSegment !== void 0) {
parts.push(...nextSegment);
if (!ch || ch === CLOSE_CURL) {
break;
}
if (nextSegment.length === 0 && ch) {
throw new Error(`Unexpected character: ${ch}`);
}
next(SEGMENT_SEPARATOR);
nextSegment = parseSegmentAndBrackets();
}
return toPath(parts);
};
try {
const result = parsePath();
return {
status: true,
path: result
};
} catch (e) {
return {
status: false,
error: e.message
};
}
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding/utils.ts
function isBinding(binding) {
return !(typeof binding === "string" || Array.isArray(binding));
}
function maybeConvertToNum(i) {
const asInt = parseInt(i, 10);
if (isNaN(asInt)) {
return i;
}
return asInt;
}
function getBindingSegments(binding) {
if (Array.isArray(binding)) {
return binding;
}
if (typeof binding === "string") {
return binding.split(".");
}
return binding.asArray();
}
function findInArray(array, key, value) {
return array.findIndex((obj) => {
if (obj && typeof obj === "object") {
return obj[key] == value;
}
return false;
});
}
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding/binding.ts
var BindingInstance = class _BindingInstance {
constructor(raw, factory = (rawBinding) => new _BindingInstance(rawBinding)) {
const split = Array.isArray(raw) ? raw : raw.split(".");
this.split = split.map((segment) => {
if (typeof segment === "number") {
return segment;
}
const tryNum = Number(segment);
return isNaN(tryNum) ? segment : tryNum;
});
Object.freeze(this.split);
this.joined = this.split.join(".");
this.factory = factory;
}
asArray() {
return this.split;
}
asString() {
return this.joined;
}
/**
* Check to see if the given binding is a sub-path of the current one
*/
contains(binding) {
const bindingAsArray = binding.asArray();
if (bindingAsArray.length < this.split.length) {
return false;
}
for (let i = 0; i < this.split.length; i++) {
if (this.split[i] !== bindingAsArray[i]) {
return false;
}
}
return true;
}
relative(binding) {
return this.asArray().slice(binding.asArray().length);
}
parent() {
return this.factory(this.split.slice(0, -1));
}
key() {
return this.split[this.split.length - 1];
}
/**
* This is a utility method to get a binding that is a descendent of this binding
*
* @param relative - The relative path to descend to
*/
descendent(relative) {
const descendentSegments = getBindingSegments(relative);
return this.factory(this.split.concat(descendentSegments));
}
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding/resolver.ts
import { NestedError } from "ts-nested-error";
function resolveBindingAST(bindingPathNode, options, hooks) {
const context = {
updates: {},
path: []
};
function getValueForNode(node) {
if (node.name === "Value") {
return node.value;
}
if (node.name === "PathNode") {
const nestedResolvedValue = resolveBindingAST(node, options);
if (nestedResolvedValue.updates) {
context.updates = {
...context.updates,
...nestedResolvedValue.updates
};
}
try {
return options.convertToPath(
options.getValue(nestedResolvedValue.path)
);
} catch (e) {
throw new NestedError(
`Unable to resolve path segment: ${nestedResolvedValue.path}`,
e
);
}
}
if (node.name === "Expression") {
try {
const actualValue = options.evaluate(node.value);
return options.convertToPath(actualValue);
} catch (e) {
throw new NestedError(`Unable to resolve path: ${node.value}`, e);
}
}
throw new Error(`Unable to resolve value for node: ${node.name}`);
}
function appendPathSegments(segment) {
if (typeof segment === "string" && segment.indexOf(".") > -1) {
segment.split(".").forEach((i) => {
context.path.push(maybeConvertToNum(i));
});
} else {
context.path.push(segment);
}
}
function resolveNode(_node) {
const resolvedNode = hooks?.beforeResolveNode.call(_node, { ...context, ...options }) ?? _node;
switch (resolvedNode.name) {
case "Expression":
case "PathNode":
appendPathSegments(getValueForNode(resolvedNode));
break;
case "Value":
appendPathSegments(resolvedNode.value);
break;
case "Query": {
const objToQuery = options.getValue(context.path) ?? [];
const { key, value } = resolvedNode;
const resolvedKey = getValueForNode(key);
const resolvedValue = value && getValueForNode(value);
const index = findInArray(objToQuery, resolvedKey, resolvedValue);
if (index === void 0 || index === -1) {
context.updates[[...context.path, objToQuery.length, resolvedKey].join(".")] = resolvedValue;
context.path.push(objToQuery.length);
} else {
context.path.push(index);
}
break;
}
case "Concatenated":
context.path.push(resolvedNode.value.map(getValueForNode).join(""));
break;
default:
throw new Error(`Unsupported node type: ${resolvedNode.name}`);
}
}
bindingPathNode.path.forEach(resolveNode);
return {
path: context.path,
updates: Object.keys(context.updates ?? {}).length > 0 ? context.updates : void 0
};
}
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/binding/index.ts
var SIMPLE_BINDING_REGEX = /^[\w\-@]+(\.[\w\-@]+)*$/;
var BINDING_BRACKETS_REGEX = /[\s()*=`{}'"[\]]/;
var LAZY_BINDING_REGEX = /^[^.]+(\..+)*$/;
var DEFAULT_OPTIONS = {
get: () => {
throw new Error("Not Implemented");
},
set: () => {
throw new Error("Not Implemented");
},
evaluate: () => {
throw new Error("Not Implemented");
}
};
var BindingParser = class {
constructor(options) {
this.hooks = {
skipOptimization: new SyncBailHook(),
beforeResolveNode: new SyncWaterfallHook()
};
this.parserOptions = { ...DEFAULT_OPTIONS, ...options };
this.cache = {};
this.parseCache = {};
this.parse = this.parse.bind(this);
}
/**
* Takes a binding path, parses it, and returns an equivalent, normalized
* representation of that path.
*/
normalizePath(path, resolveOptions) {
if (!BINDING_BRACKETS_REGEX.test(path) && LAZY_BINDING_REGEX.test(path) && this.hooks.skipOptimization.call(path) !== true) {
return { path: path.split("."), updates: void 0 };
}
const ast = this.parseCache[path] ?? parse(path);
this.parseCache[path] = ast;
if (typeof ast !== "object" || !ast?.status) {
throw new TypeError(
`Cannot normalize path "${path}": ${ast?.error ?? "Unknown Error."}`
);
}
try {
return resolveBindingAST(ast.path, resolveOptions, this.hooks);
} catch (e) {
throw new NestedError2(`Cannot resolve binding: ${path}`, e);
}
}
getBindingForNormalizedResult(normalized) {
const normalizedStr = normalized.path.join(".");
if (this.cache[normalizedStr]) {
return this.cache[normalizedStr];
}
const created = new BindingInstance(
normalizedStr === "" ? [] : normalized.path,
this.parse
);
this.cache[normalizedStr] = created;
return created;
}
parse(rawBinding, overrides = {}) {
if (isBinding(rawBinding)) {
return rawBinding;
}
const options = {
...this.parserOptions,
...overrides
};
let updates = {};
const joined = Array.isArray(rawBinding) ? rawBinding.join(".") : String(rawBinding);
const normalizeConfig = {
getValue: (path) => {
const normalized2 = this.normalizePath(path.join("."), normalizeConfig);
return options.get(this.getBindingForNormalizedResult(normalized2));
},
evaluate: (exp) => {
return options.evaluate(exp);
},
convertToPath: (path) => {
if (path === void 0) {
throw new Error(
"Attempted to convert undefined value to binding path"
);
}
if (typeof path !== "string" && typeof path !== "number" && typeof path !== "boolean") {
throw new Error(
`Attempting to convert ${typeof path} to a binding path.`
);
}
const normalized2 = this.normalizePath(String(path), normalizeConfig);
if (normalized2.updates) {
updates = {
...updates,
...normalized2.updates
};
}
const joinedNormalizedPath = normalized2.path.join(".");
if (joinedNormalizedPath === "") {
throw new Error("Nested path resolved to an empty path");
}
return joinedNormalizedPath;
}
};
const normalized = this.normalizePath(joined, normalizeConfig);
if (normalized.updates) {
updates = {
...updates,
...normalized.updates
};
}
const updateKeys = Object.keys(updates);
if (!options.readOnly && updateKeys.length > 0) {
const updateTransaction = updateKeys.map(
(updatedBinding) => [
this.parse(updatedBinding),
updates[updatedBinding]
]
);
options.set(updateTransaction);
}
return this.getBindingForNormalizedResult(normalized);
}
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/data/dependency-tracker.ts
var DependencyTracker = class {
constructor() {
this.readDeps = /* @__PURE__ */ new Set();
this.writeDeps = /* @__PURE__ */ new Set();
this.namedDependencySets = {};
this.namedSet = "core";
this.createSubset("core");
this.createSubset("children");
}
createSubset(name, force = false) {
if (force || !this.namedDependencySets[name]) {
this.namedDependencySets[name] = {
readDeps: /* @__PURE__ */ new Set(),
writeDeps: /* @__PURE__ */ new Set()
};
}
}
/** Grab all of the bindings that this depended on */
getDependencies(name) {
if (name !== void 0) {
return this.namedDependencySets?.[name]?.readDeps ?? /* @__PURE__ */ new Set();
}
return this.readDeps;
}
trackSubset(name) {
this.createSubset(name);
this.namedSet = name;
}
trackDefault() {
this.namedSet = "core";
}
/** Grab all of the bindings this wrote to */
getModified(name) {
if (name !== void 0) {
return this.namedDependencySets?.[name]?.writeDeps ?? /* @__PURE__ */ new Set();
}
return this.writeDeps;
}
/**
* Check to see if the dataModel has read the value at the given binding
*
* @param binding - The binding you want to check for
*/
readsBinding(binding) {
return this.readDeps.has(binding);
}
/**
* Check to see if the dataModel has written to the binding
*/
writesBinding(binding) {
return this.writeDeps.has(binding);
}
/** Reset all tracking of dependencies */
reset() {
this.readDeps = /* @__PURE__ */ new Set();
this.writeDeps = /* @__PURE__ */ new Set();
this.namedDependencySets = {};
this.namedSet = "core";
this.createSubset("core", true);
this.createSubset("children", true);
}
addReadDep(binding, namedSet = this.namedSet) {
if (namedSet) {
this.namedDependencySets?.[namedSet]?.readDeps.add(binding);
}
this.readDeps.add(binding);
}
addWriteDep(binding, namedSet = this.namedSet) {
if (namedSet) {
this.namedDependencySets?.[namedSet]?.writeDeps.add(binding);
}
this.writeDeps.add(binding);
}
addChildReadDep(binding) {
this.addReadDep(binding, "children");
}
};
var DependencyMiddleware = class extends DependencyTracker {
constructor() {
super();
this.get = this.get.bind(this);
this.set = this.set.bind(this);
}
set(transaction, options, next) {
transaction.forEach(([binding]) => this.addWriteDep(binding));
return next?.set(transaction, options) ?? [];
}
get(binding, options, next) {
this.addReadDep(binding);
return next?.get(binding, options);
}
delete(binding, options, next) {
this.addWriteDep(binding);
return next?.delete(binding, options);
}
};
var DependencyModel = class extends DependencyTracker {
constructor(rootModel) {
super();
this.rootModel = rootModel;
this.set = this.set.bind(this);
this.get = this.get.bind(this);
}
set(transaction, options) {
transaction.forEach(([binding]) => this.addWriteDep(binding));
return this.rootModel.set(transaction, options);
}
get(binding, options) {
this.addReadDep(binding);
return this.rootModel.get(binding, options);
}
delete(binding, options) {
this.addWriteDep(binding);
return this.rootModel.delete(binding, options);
}
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/data/model.ts
import { SyncHook } from "tapable-ts";
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/data/noop-model.ts
var NOOPDataModel = class {
get() {
return void 0;
}
set() {
return [];
}
delete() {
}
};
var NOOP_MODEL = new NOOPDataModel();
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/data/model.ts
var ROOT_BINDING = new BindingInstance([]);
function withParser(model, parseBinding) {
function maybeParse(binding, readOnly) {
const parsed = isBinding(binding) ? binding : parseBinding(binding, {
get: model.get,
set: model.set,
readOnly
});
if (!parsed) {
throw new Error("Unable to parse binding");
}
return parsed;
}
return {
get(binding, options) {
return model.get(maybeParse(binding, true), options);
},
set(transaction, options) {
return model.set(
transaction.map(([key, val]) => [maybeParse(key, false), val]),
options
);
},
delete(binding, options) {
return model.delete(maybeParse(binding, false), options);
}
};
}
function toModel(middleware, defaultOptions, next) {
if (!next) {
return middleware;
}
return {
get: (binding, options) => {
const resolvedOptions = options ?? defaultOptions;
if (middleware.get) {
return middleware.get(binding, resolvedOptions, next);
}
return next?.get(binding, resolvedOptions);
},
set: (transaction, options) => {
const resolvedOptions = options ?? defaultOptions;
if (middleware.set) {
return middleware.set(transaction, resolvedOptions, next);
}
return next?.set(transaction, resolvedOptions);
},
delete: (binding, options) => {
const resolvedOptions = options ?? defaultOptions;
if (middleware.delete) {
return middleware.delete(binding, resolvedOptions, next);
}
return next?.delete(binding, resolvedOptions);
}
};
}
function constructModelForPipeline(pipeline) {
if (pipeline.length === 0) {
return NOOP_MODEL;
}
if (pipeline.length === 1) {
return toModel(pipeline[0]);
}
function createModelWithOptions(options) {
const model = pipeline.reduce(
(nextModel, middleware) => toModel(middleware, options, nextModel),
void 0
) ?? NOOP_MODEL;
return model;
}
return {
get: (binding, options) => {
return createModelWithOptions(options)?.get(binding, options);
},
set: (transaction, options) => {
return createModelWithOptions(options)?.set(transaction, options);
},
delete: (binding, options) => {
return createModelWithOptions(options)?.delete(binding, options);
}
};
}
var PipelinedDataModel = class {
constructor(pipeline = []) {
this.hooks = {
onSet: new SyncHook()
};
this.pipeline = pipeline;
this.effectiveDataModel = constructModelForPipeline(this.pipeline);
}
setMiddleware(handlers) {
this.pipeline = handlers;
this.effectiveDataModel = constructModelForPipeline(handlers);
}
addMiddleware(handler) {
this.pipeline = [...this.pipeline, handler];
this.effectiveDataModel = constructModelForPipeline(this.pipeline);
}
reset(model = {}) {
this.pipeline.forEach((middleware) => {
if ("reset" in middleware) {
middleware.reset?.();
}
});
this.set([[ROOT_BINDING, model]]);
}
set(transaction, options) {
const appliedTransaction = this.effectiveDataModel.set(
transaction,
options
);
this.hooks.onSet.call(transaction);
return appliedTransaction;
}
get(binding, options) {
return this.effectiveDataModel.get(binding, options);
}
delete(binding, options) {
return this.effectiveDataModel.delete(binding, options);
}
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/data/local-model.ts
import get from "dlv";
import { setIn, omit, removeAt } from "timm";
var LocalModel = class {
constructor(model = {}) {
this.model = model;
this.get = this.get.bind(this);
this.set = this.set.bind(this);
}
reset(model = {}) {
this.model = model;
}
get(binding) {
if (!binding || !binding.asString()) {
return this.model;
}
return get(this.model, binding.asArray());
}
set(transaction) {
const effectiveOperations = [];
transaction.forEach(([binding, value]) => {
const oldValue = this.get(binding);
this.model = setIn(this.model, binding.asArray(), value);
effectiveOperations.push({ binding, oldValue, newValue: value });
});
return effectiveOperations;
}
delete(binding) {
const parentBinding = binding.parent();
if (parentBinding) {
const parentValue = this.get(parentBinding);
if (parentValue !== void 0) {
if (Array.isArray(parentValue)) {
this.model = setIn(
this.model,
parentBinding.asArray(),
removeAt(parentValue, binding.key())
);
} else {
this.model = setIn(
this.model,
parentBinding.asArray(),
omit(parentValue, binding.key())
);
}
}
}
}
};
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/expressions/evaluator.ts
import { SyncWaterfallHook as SyncWaterfallHook2, SyncBailHook as SyncBailHook2 } from "tapable-ts";
import { NestedError as NestedError3 } from "ts-nested-error";
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/expressions/types.ts
var ExpNodeOpaqueIdentifier = Symbol("Expression Node ID");
function isExpressionNode(x) {
return typeof x === "object" && x !== null && !Array.isArray(x) && x.__id === ExpNodeOpaqueIdentifier;
}
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/expressions/parser.ts
var PERIOD_CODE = 46;
var COMMA_CODE = 44;
var SQUOTE_CODE = 39;
var DQUOTE_CODE = 34;
var OPAREN_CODE = 40;
var CPAREN_CODE = 41;
var OBRACK_CODE = 91;
var CBRACK_CODE = 93;
var QUMARK_CODE = 63;
var SEMCOL_CODE = 59;
var COLON_CODE = 58;
var OCURL_CODE = 123;
var CCURL_CODE = 125;
var t = true;
var unaryOps = { "-": t, "!": t, "~": t, "+": t };
var binaryOps = {
"=": 3,
"+=": 3,
"-=": 3,
"&=": 3,
"|=": 3,
// Conditional: 4,
"||": 5,
"&&": 6,
"|": 7,
"^": 8,
"&": 9,
"==": 10,
"!=": 10,
"===": 10,
"!==": 10,
"<": 11,
">": 11,
"<=": 11,
">=": 11,
"<<": 12,
">>": 12,
">>>": 12,
"+": 13,
"-": 13,
"*": 14,
"/": 14,
"%": 14
};
function throwError(message, index) {
const err = new Error(`${message} at character ${index}`);
err.index = index;
err.description = message;
throw err;
}
function createSpanningLocation(start, end) {
if (!start || !end) {
return;
}
return {
start: start.start,
end: end.end
};
}
function getMaxKeyLen(obj) {
let maxLen = 0;
Object.keys(obj).forEach((key) => {
if (key.length > maxLen && Object.prototype.hasOwnProperty.call(obj, key)) {
maxLen = key.length;
}
});
return maxLen;
}
var maxUnopLen = getMaxKeyLen(unaryOps);
var maxBinopLen = getMaxKeyLen(binaryOps);
var literals = {
true: true,
false: false,
null: null,
undefined: void 0
};
var thisStr = "this";
function binaryPrecedence(opVal) {
return binaryOps[opVal] || 0;
}
function createBinaryExpression(operator, left, right, location) {
let type;
if (operator === "||" || operator === "&&") {
type = "LogicalExpression";
} else if (operator === "=") {
type = "Assignment";
} else if (operator === "+=" || operator === "-=" || operator === "&=" || operator === "|=") {
type = "Modification";
} else {
type = "BinaryExpression";
}
return {
__id: ExpNodeOpaqueIdentifier,
type,
operator,
left,
right,
location
};
}
function isDecimalDigit(ch) {
return ch >= 48 && ch <= 57;
}
function isIdentifierStart(ch) {
return ch === 36 || ch === 95 || // `$` and `_`
ch >= 65 && ch <= 90 || // A...Z
ch >= 97 && ch <= 122;
}
function isIdentifierPart(ch) {
return ch === 36 || ch === 95 || // `$` and `_`
ch >= 65 && ch <= 90 || // A...Z
ch >= 97 && ch <= 122 || // A...z
ch >= 48 && ch <= 57;
}
function isModelRefStart(ch0, ch1) {
return ch0 === OCURL_CODE && ch1 === OCURL_CODE;
}
function parseExpression(expr, options) {
const strictMode = options?.strict ?? true;
const charAtFunc = expr.charAt;
const charCodeAtFunc = expr.charCodeAt;
const { length } = expr;
let index = 0;
const getLocation = (startChar) => {
return {
start: {
character: startChar
},
end: {
character: index
}
};
};
function exprI(i) {
return charAtFunc.call(expr, i);
}
function exprICode(i) {
return charCodeAtFunc.call(expr, i);
}
function gobbleObjects() {
const attributes = [];
let closed = false;
let shouldDefineKey = true;
let key;
let value;
let chCode;
const startCharIndex = index;
++index;
while (index < length) {
gobbleSpaces();
chCode = exprICode(index);
if (chCode === CCURL_CODE) {
if (key) {
throwError("A key was defined but a value was not", index);
}
index++;
closed = true;
break;
} else if (shouldDefineKey) {
if (chCode !== SQUOTE_CODE && chCode !== DQUOTE_CODE) {
throwError("An object must start wtih a key", index);
}
key = gobbleStringLiteral();
gobbleSpaces();
if (exprICode(index) === COLON_CODE) {
index++;
shouldDefineKey = false;
} else {
throwError("A colon must follow an object key", index);
}
} else {
value = gobbleExpression();
attributes.push({ key, value });
gobbleSpaces();
chCode = exprICode(index);
if (chCode === COMMA_CODE) {
index++;
} else if (chCode !== CCURL_CODE) {
throwError("Please add a comma to add another key", index);
}
shouldDefineKey = true;
key = void 0;
value = void 0;
}
chCode = exprICode(index);
}
if (!closed) {
throwError(`Unclosed brace in object`, index);
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "Object",
attributes,
location: getLocation(startCharIndex)
};
}
function gobbleSpaces() {
let ch = exprICode(index);
while (ch === 32 || ch === 9) {
ch = exprICode(++index);
}
}
function gobbleExpression() {
const test = gobbleBinaryExpression();
gobbleSpaces();
const startCharIndex = index;
if (index < length && exprICode(index) === QUMARK_CODE) {
index++;
const consequent = gobbleExpression();
if (!consequent) {
throwError("Expected expression", index);
}
gobbleSpaces();
if (exprICode(index) === COLON_CODE) {
index++;
const alternate = gobbleExpression();
if (!alternate) {
throwError("Expected expression", index);
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "ConditionalExpression",
test,
consequent,
alternate,
location: getLocation(startCharIndex)
};
}
throwError("Expected :", index);
}
return test;
}
function gobbleBinaryOp() {
gobbleSpaces();
let toCheck = expr.substr(index, maxBinopLen);
let tcLen = toCheck.length;
while (tcLen > 0) {
if (Object.prototype.hasOwnProperty.call(binaryOps, toCheck)) {
index += tcLen;
return toCheck;
}
toCheck = toCheck.substr(0, --tcLen);
}
return false;
}
function gobbleBinaryExpression() {
let node;
let prec;
let i;
let left = gobbleToken();
let biop = gobbleBinaryOp();
if (!biop) {
return left;
}
let biopInfo = { value: biop, prec: binaryPrecedence(biop) };
let right = gobbleToken();
if (!right) {
throwError(`Expected expression after ${biop}`, index);
}
const stack = [left, biopInfo, right];
biop = gobbleBinaryOp();
while (biop) {
prec = binaryPrecedence(biop);
if (prec === 0) {
break;
}
biopInfo = { value: biop, prec };
while (stack.length > 2 && prec <= stack[stack.length - 2].prec) {
right = stack.pop();
biop = stack.pop().value;
left = stack.pop();
node = createBinaryExpression(
biop,
left,
right,
createSpanningLocation(left.location, right.location)
);
stack.push(node);
}
node = gobbleToken();
if (!node) {
throwError(`Expected expression after ${biop}`, index);
}
stack.push(biopInfo, node);
biop = gobbleBinaryOp();
}
i = stack.length - 1;
node = stack[i];
while (i > 1) {
node = createBinaryExpression(
stack[i - 1].value,
stack[i - 2],
node,
createSpanningLocation(stack[i - 2].location, node.location)
);
i -= 2;
}
return node;
}
function gobbleToken() {
gobbleSpaces();
const ch = exprICode(index);
const startCharIndex = index;
if (isDecimalDigit(ch) || ch === PERIOD_CODE) {
return gobbleNumericLiteral();
}
if (ch === SQUOTE_CODE || ch === DQUOTE_CODE) {
return gobbleStringLiteral();
}
if (isIdentifierStart(ch) || ch === OPAREN_CODE) {
return gobbleVariable();
}
if (ch === OBRACK_CODE) {
return gobbleArray();
}
if (isModelRefStart(ch, exprICode(index + 1))) {
return gobbleModelRef();
}
if (ch === OCURL_CODE) {
return gobbleObjects();
}
let toCheck = expr.substr(index, maxUnopLen);
let tcLen = toCheck.length;
while (tcLen > 0) {
if (Object.prototype.hasOwnProperty.call(unaryOps, toCheck)) {
index += tcLen;
return {
__id: ExpNodeOpaqueIdentifier,
type: "UnaryExpression",
operator: toCheck,
argument: gobbleToken(),
prefix: true,
location: getLocation(startCharIndex)
};
}
toCheck = toCheck.substr(0, --tcLen);
}
return false;
}
function gobbleNumericLiteral() {
let num = "";
const startCharIndex = index;
while (isDecimalDigit(exprICode(index))) {
num += exprI(index++);
}
if (exprICode(index) === PERIOD_CODE) {
num += exprI(index++);
while (isDecimalDigit(exprICode(index))) {
num += exprI(index++);
}
}
let ch = exprI(index);
if (ch === "e" || ch === "E") {
num += exprI(index++);
ch = exprI(index);
if (ch === "+" || ch === "-") {
num += exprI(index++);
}
while (isDecimalDigit(exprICode(index))) {
num += exprI(index++);
}
if (!isDecimalDigit(exprICode(index - 1))) {
throwError(`Expected exponent (${num}${exprI(index)})`, index);
}
}
const chCode = exprICode(index);
if (isIdentifierStart(chCode)) {
throwError(
`Variable names cannot start with a number (${num}${exprI(index)})`,
index
);
} else if (chCode === PERIOD_CODE) {
throwError("Unexpected period", index);
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "Literal",
value: parseFloat(num),
raw: num,
location: getLocation(startCharIndex)
};
}
function gobbleStringLiteral() {
const quote = exprI(index++);
let str = "";
let closed = false;
const startCharIndex = index;
while (index < length) {
let ch = exprI(index++);
if (ch === quote) {
closed = true;
break;
}
if (ch !== "\\") {
str += ch;
continue;
}
ch = exprI(index++);
switch (ch) {
case "n":
str += "\n";
break;
case "r":
str += "\r";
break;
case "t":
str += " ";
break;
case "b":
str += "\b";
break;
case "f":
str += "\f";
break;
case "v":
str += "\v";
break;
default:
}
}
if (!closed) {
throwError(`Unclosed quote after "${str}"`, index);
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "Literal",
value: str,
raw: `${quote}${str}${quote}`,
location: getLocation(startCharIndex)
};
}
function gobbleModelRef() {
let str = "";
let closed = false;
let openBraceCount = 1;
const startCharIndex = index;
index += 2;
while (index < length) {
const ch = exprI(index++);
if (ch === "}" && exprICode(index) === CCURL_CODE) {
index++;
openBraceCount--;
if (openBraceCount === 0) {
closed = true;
break;
}
str += "}}";
} else if (ch === "{" && exprICode(index) === OCURL_CODE) {
openBraceCount++;
str += "{{";
index++;
} else {
str += ch;
}
}
if (!closed) {
throwError(`Unclosed brace after "${str}"`, index);
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "ModelRef",
ref: str,
location: getLocation(startCharIndex)
};
}
function gobbleIdentifier() {
const start = index;
let ch = exprICode(start);
if (isIdentifierStart(ch)) {
index++;
} else {
throwError(`Unexpected ${exprI(index)}`, index);
}
while (index < length) {
ch = exprICode(index);
if (isIdentifierPart(ch)) {
index++;
} else {
break;
}
}
const identifier = expr.slice(start, index);
if (Object.prototype.hasOwnProperty.call(literals, identifier)) {
return {
__id: ExpNodeOpaqueIdentifier,
type: "Literal",
value: literals[identifier],
raw: identifier,
location: getLocation(start)
};
}
if (identifier === thisStr) {
return {
__id: ExpNodeOpaqueIdentifier,
type: "ThisExpression",
location: getLocation(start)
};
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "Identifier",
name: identifier,
location: getLocation(start)
};
}
function gobbleArguments(termination) {
const args = [];
let charIndex;
let node;
while (index < length) {
gobbleSpaces();
charIndex = exprICode(index);
if (charIndex === termination) {
index++;
break;
}
if (charIndex === COMMA_CODE) {
index++;
continue;
}
node = gobbleExpression();
if (!node || node.type === "Compound") {
throwError("Expected comma", index);
}
args.push(node);
}
if (strictMode && charIndex !== termination) {
throwError(`Expected ${String.fromCharCode(termination)}`, index);
}
return args;
}
function gobbleVariable() {
let charIndex = exprICode(index);
let node = charIndex === OPAREN_CODE ? gobbleGroup() : gobbleIdentifier();
const startCharIndex = index;
gobbleSpaces();
charIndex = exprICode(index);
while (charIndex === PERIOD_CODE || charIndex === OBRACK_CODE || charIndex === OPAREN_CODE) {
index++;
if (charIndex === PERIOD_CODE) {
gobbleSpaces();
node = {
__id: ExpNodeOpaqueIdentifier,
type: "MemberExpression",
computed: false,
object: node,
property: gobbleIdentifier(),
location: getLocation(startCharIndex)
};
} else if (charIndex === OBRACK_CODE) {
node = {
__id: ExpNodeOpaqueIdentifier,
type: "MemberExpression",
computed: true,
object: node,
property: gobbleExpression(),
location: getLocation(startCharIndex)
};
gobbleSpaces();
charIndex = exprICode(index);
if (charIndex !== CBRACK_CODE) {
throwError("Unclosed [", index);
}
index++;
} else if (charIndex === OPAREN_CODE) {
node = {
__id: ExpNodeOpaqueIdentifier,
type: "CallExpression",
args: gobbleArguments(CPAREN_CODE),
callTarget: node,
location: getLocation(startCharIndex)
};
}
gobbleSpaces();
charIndex = exprICode(index);
}
return node;
}
function gobbleGroup() {
index++;
const node = gobbleExpression();
gobbleSpaces();
if (exprICode(index) === CPAREN_CODE) {
index++;
return node;
}
throwError("Unclosed (", index);
}
function gobbleArray() {
const startCharIndex = index;
index++;
return {
__id: ExpNodeOpaqueIdentifier,
type: "ArrayExpression",
elements: gobbleArguments(CBRACK_CODE),
location: getLocation(startCharIndex)
};
}
const nodes = [];
try {
while (index < length) {
const chIndex = exprICode(index);
if (chIndex === SEMCOL_CODE || chIndex === COMMA_CODE) {
index++;
continue;
}
const node = gobbleExpression();
if (node) {
nodes.push(node);
} else if (strictMode && index < length) {
throwError(`Unexpected "${exprI(index)}"`, index);
}
}
if (nodes.length === 1) {
return nodes[0];
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "Compound",
body: nodes,
location: getLocation(0)
};
} catch (e) {
if (strictMode || !(e instanceof Error)) {
throw e;
}
return {
__id: ExpNodeOpaqueIdentifier,
type: "Compound",
body: nodes,
location: getLocation(0),
error: e
};
}
}
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/expressions/evaluator-functions.ts
var evaluator_functions_exports = {};
__export(evaluator_functions_exports, {
conditional: () => conditional,
deleteDataVal: () => deleteDataVal,
getDataVal: () => getDataVal,
setDataVal: () => setDataVal
});
var setDataVal = (_context, binding, value) => {
_context.model.set([[binding, value]]);
};
var getDataVal = (_context, binding) => {
return _context.model.get(binding);
};
var deleteDataVal = (_context, binding) => {
return _context.model.delete(binding);
};
var conditional = (ctx, condition, ifTrue, ifFalse) => {
const resolution = ctx.evaluate(condition);
if (resolution) {
return ctx.evaluate(ifTrue);
}
if (ifFalse) {
return ctx.evaluate(ifFalse);
}
return null;
};
conditional.resolveParams = false;
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/expressions/utils.ts
function withoutContext(fn) {
return (_context, ...args) => fn(...args);
}
function isInRange(position, location) {
return position.character >= location.start.character && position.character <= location.end.character;
}
function findClosestNodeAtPosition(node, position) {
switch (node.type) {
case "Modification":
case "Assignment":
case "LogicalExpression":
case "BinaryExpression": {
const check = findClosestNodeAtPosition(node.left, position) ?? findClosestNodeAtPosition(node.right, position);
if (check) {
return check;
}
break;
}
case "UnaryExpression": {
const checkArg = findClosestNodeAtPosition(node.argument, position);
if (checkArg) {
return checkArg;
}
break;
}
case "MemberExpression": {
const checkObject = findClosestNodeAtPosition(node.object, position) ?? findClosestNodeAtPosition(node.property, position);
if (checkObject) {
return checkObject;
}
break;
}
case "ConditionalExpression": {
const checkObject = findClosestNodeAtPosition(node.test, position) ?? findClosestNodeAtPosition(node.consequent, position) ?? findClosestNodeAtPosition(node.alternate, position);
if (checkObject) {
return checkObject;
}
break;
}
case "ArrayExpression":
case "Compound": {
const elements = node.type === "ArrayExpression" ? node.elements : node.body;
const anyElements = elements.find(
(e) => findClosestNodeAtPosition(e, position)
);
if (anyElements) {
return anyElements;
}
break;
}
case "Object": {
const checkObject = node.attributes.reduce(
(found, next) => {
return found ?? findClosestNodeAtPosition(next.key, position) ?? findClosestNodeAtPosition(next.value, position);
},
void 0
);
if (checkObject) {
return checkObject;
}
break;
}
case "CallExpression": {
const anyArgs = node.args.find((arg) => {
return findClosestNodeAtPosition(arg, position);
}) ?? findClosestNodeAtPosition(node.callTarget, position);
if (anyArgs) {
return anyArgs;
}
break;
}
}
if (node.location && isInRange(position, node.location)) {
return node;
}
}
function isObjectExpression(expr) {
if (isExpressionNode(expr)) {
return false;
}
return typeof expr === "object" && expr !== null && !Array.isArray(expr) && "value" in expr;
}
function isErrorWithLocation(error) {
return error.index !== void 0 && error.description !== void 0;
}
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/core/player/src/expressions/evaluator.ts
var andandOperator = (ctx, a, b) => {
return ctx.evaluate(a) && ctx.evaluate(b);
};
andandOperator.resolveParams = false;
var ororOperator = (ctx, a, b) => {
return ctx.evaluate(a) || ctx.evaluate(b);
};
ororOperator.resolveParams = false;
var DEFAULT_BINARY_OPERATORS = {
// TODO: A lot of these functions used to do type coercion. Not sure if we want to keep that behavior or not.
"+": (a, b) => a + b,
"-": (a, b) => a - b,
"*": (a, b) => a * b,
"/": (a, b) => a / b,
"%": (a, b) => a % b,
// eslint-disable-next-line
"==": (a, b) => a == b,
// eslint-disable-next-line
"!=": (a, b) => a != b,
">": (a, b) => a > b,
">=": (a, b) => a >= b,
"<": (a, b) => a < b,
"<=": (a, b) => a <= b,
"&&": andandOperator,
"||": ororOperator,
"!==": (a, b) => a !== b,
"===": (a, b) => a === b,
// eslint-disable-next-line
"|": (a, b) => a | b,
// eslint-disable-next-line
"&": (a, b) => a & b,
"+=": (a, b) => a + b,
"-=": (a, b) => a - b,
// eslint-disable-next-line
"&=": (a, b) => a & b,
// eslint-disable-next-line
"|=": (a, b) => a | b
};
var DEFAULT_UNARY_OPERATORS = {
"-": (a) => -a,
"+": (a) => Number(a),
"!": (a) => !a
};
var ExpressionEvaluator = class {
constructor(defaultOptions) {
this.vars = {};
this.hooks = {
/** Resolve an AST node for an expression to a value */
resolve: new SyncWaterfallHook2(),
/** Gets the options that will be passed in calls to the resolve hook */
resolveOptions: new SyncWaterfallHook2(),
/** Allows users to change the expression to be evaluated before processing */
beforeEvaluate: new SyncWaterfallHook2(),
/**
* An optional means of handling an error in the expression execution
* Return true if handled, to stop propagation of the error
*/
onError: new SyncBailHook2()
};
this.expressionsCache = /* @__PURE__ */ new Map();
this.operators = {
binary: new Map(Object.entries(DEFAULT_BINARY_OPERATORS)),
unary: new Map(Object.entries(DEFAULT_UNARY_OPERATORS)),
expressions: new Map(
Object.entries(evaluator_functions_exports)
)
};
this.defaultHookOptions = {
...defaultOptions,
evaluate: (expr) => this.evaluate(expr, this.defaultHookOptions),
resolveNode: (node) => this._execAST(node, this.defaultHookOptions)
};
this.hooks.resolve.tap("ExpressionEvaluator", this._resolveNode.bind(this));
this.evaluate = this.evaluate.bind(this);
}
reset() {
this.expressionsCache.clear();
}
evaluate(expr, options) {
const resolvedOpts = this.hooks.resolveOptions.call({
...this.defaultHookOptions,
...options,
resolveNode: (node) => this._execAST(node, resolvedOpts)
});
let expression = this.hooks.beforeEvaluate.call(expr, resolvedOpts) ?? expr;
while (isObjectExpression(expression)) {
expression = expression.value;
}
if (typeof expression === "number" || typeof expression === "boolean" || expression === void 0 || expression === null) {
return expression;
}
if (isExpressionNode(expression)) {
return this._execAST(expression, resolvedOpts);
}
if (Array.isArray(expression)) {
return expression.reduce(
(_nothing, exp) => this.evaluate(exp, options),
null
);
}
return this._execString(String(expression), resolvedOpts);
}
addExpressionFunction(name, handler) {
this.operators.expressions.set(name, handler);
}
addBinaryOperator(operator, handler) {
this.operators.binary.set(operator, handler);
}
addUnaryOperator(operator, handler) {
this.operators.unary.set(operator, handler);
}
setExpressionVariable(name, value) {
this.vars[name] = value;
}
getExpressionVariable(name) {
return this.vars[name];
}
_execAST(node, options) {
return this.hooks.resolve.call(void 0, node, options);
}
_execString(exp, options) {
if (exp === "") {
return exp;
}
const matches = exp.match(/^@\[(.*)\]@$/);
let matchedExp = exp;
if (matches) {
[, matchedExp] = Array.from(matches);
}
let storedAST;
try {
storedAST = this.expressionsCache.get(matchedExp) ?? parseExpression(matchedExp, { strict: options.strict });
this.expressionsCache.set(matchedExp, storedAST);
} catch (e) {
if (options.throwErrors || !this.hooks.onError.call(e)) {
throw new NestedError3(`Error parsing expression: ${exp}`, e);
}
return;
}
try {
return this._execAST(storedAST, options);
} catch (e) {
if (options.throwErrors || !this.hooks.onError.call(e)) {
throw new NestedError3(`Error evaluating expression: ${exp}`, e);
}
}
}
_resolveNode(_currentValue, node, options) {
const { resolveNode, model } = options;
const expressionContext = {
...options,
evaluate: (expr) => this.evaluate(expr, options)
};
if (node.type === "Literal") {
return node.value;
}
if (node.type === "Identifier") {
return this.vars[node.name];
}
if (node.type === "Compound" || node.type === "ThisExpression") {
throw new Error(`Expression type: ${node.type} is not supported`);
}
if (node.type === "BinaryExpression" || node.type === "LogicalExpression") {
const operator = this.operators.binary.get(node.operator);
if (operator) {
if ("resolveParams" in operator) {
if (operator.resolveParams === false) {
return operator(expressionContext, node.left, node.right);
}