UNPKG

@player-ui/player

Version:

1,783 lines (1,763 loc) 170 kB
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); }