@here/harp-datasource-protocol
Advanced tools
Comparing version 0.27.1 to 0.28.0
@@ -11,2 +11,3 @@ import { Env, Value } from "./Env"; | ||
* A visitor for {@link Expr} nodes. | ||
* @internal | ||
*/ | ||
@@ -22,2 +23,3 @@ export interface ExprVisitor<Result, Context> { | ||
visitCallExpr(expr: CallExpr, context: Context): Result; | ||
visitLookupExpr(expr: LookupExpr, context: Context): Result; | ||
visitMatchExpr(expr: MatchExpr, context: Context): Result; | ||
@@ -30,2 +32,3 @@ visitCaseExpr(expr: CaseExpr, context: Context): Result; | ||
* The dependencies of an {@link Expr}. | ||
* @internal | ||
*/ | ||
@@ -67,3 +70,12 @@ export declare class ExprDependencies { | ||
/** | ||
* Internal state needed by {@link Expr.fromJSON} to resolve `"ref"` expressions. | ||
*/ | ||
interface ReferenceResolverState { | ||
definitions: Definitions; | ||
lockedNames: Set<string>; | ||
cache: Map<string, Expr>; | ||
} | ||
/** | ||
* The evaluation scope of an {@link Expr}. | ||
* @internal | ||
*/ | ||
@@ -188,2 +200,3 @@ export declare enum ExprScope { | ||
* A node representing a `get` expression. | ||
* @internal | ||
*/ | ||
@@ -200,2 +213,3 @@ export declare class VarExpr extends Expr { | ||
* A node representing a `literal` expression. | ||
* @internal | ||
*/ | ||
@@ -215,2 +229,3 @@ export declare abstract class LiteralExpr extends Expr { | ||
* Null literal expression. | ||
* @internal | ||
*/ | ||
@@ -229,2 +244,3 @@ export declare class NullLiteralExpr extends LiteralExpr { | ||
* Boolean literal expression. | ||
* @internal | ||
*/ | ||
@@ -239,2 +255,3 @@ export declare class BooleanLiteralExpr extends LiteralExpr { | ||
* Number literal expression. | ||
* @internal | ||
*/ | ||
@@ -249,2 +266,3 @@ export declare class NumberLiteralExpr extends LiteralExpr { | ||
* String literal expression. | ||
* @internal | ||
*/ | ||
@@ -264,2 +282,3 @@ export declare class StringLiteralExpr extends LiteralExpr { | ||
* Object literal expression. | ||
* @internal | ||
*/ | ||
@@ -275,2 +294,3 @@ export declare class ObjectLiteralExpr extends LiteralExpr { | ||
* A node reperesenting a `has` expression. | ||
* @internal | ||
*/ | ||
@@ -287,2 +307,3 @@ export declare class HasAttributeExpr extends Expr { | ||
* A node representing a `call` expression. | ||
* @internal | ||
*/ | ||
@@ -306,3 +327,27 @@ export declare class CallExpr extends Expr { | ||
/** | ||
* A `lookup` expression is a call expression using the `lookup` operator. Then only difference is | ||
* that the lookup table definition (first argument) is cached as a map for fast search | ||
* (see {@link ExprEvaluator.visitLookupExpr}). | ||
* @internal | ||
*/ | ||
export declare class LookupExpr extends CallExpr { | ||
readonly args: Expr[]; | ||
/** | ||
* Creates a lookup expression from a {@link JsonArray}. | ||
* @param node The {@link JsonArray} to parse. | ||
* @param referenceResolverState Used to resolve references to definitions. | ||
* @returns A LookupExpr instance. | ||
*/ | ||
static parseArray(node: JsonArray, referenceResolverState?: ReferenceResolverState): Expr; | ||
/** | ||
* Constructs a LookupExpr instance. | ||
* @param args Arguments of the lookup expression. At least an argument for the lookup table. | ||
*/ | ||
constructor(args: Expr[]); | ||
/** @override */ | ||
accept<Result, Context>(visitor: ExprVisitor<Result, Context>, context: Context): Result; | ||
} | ||
/** | ||
* The labels of a {@link MatchExpr} expression. | ||
* @internal | ||
*/ | ||
@@ -312,2 +357,3 @@ export declare type MatchLabel = number | string | number[] | string[]; | ||
* A node representing a `match` expression. | ||
* @internal | ||
*/ | ||
@@ -332,2 +378,3 @@ export declare class MatchExpr extends Expr { | ||
* A node representing a `case` expression. | ||
* @internal | ||
*/ | ||
@@ -345,2 +392,3 @@ export declare class CaseExpr extends Expr { | ||
* A node representing a `step` expression. | ||
* @internal | ||
*/ | ||
@@ -363,2 +411,3 @@ export declare class StepExpr extends Expr { | ||
* A node representing an `interpolate` expression. | ||
* @internal | ||
*/ | ||
@@ -365,0 +414,0 @@ export declare class InterpolateExpr extends Expr { |
"use strict"; | ||
/* | ||
* Copyright (C) 2019-2021 HERE Europe B.V. | ||
* Licensed under Apache 2.0, see full license in LICENSE | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
@@ -18,3 +13,8 @@ if (k2 === undefined) k2 = k; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.InterpolateExpr = exports.StepExpr = exports.CaseExpr = exports.MatchExpr = exports.CallExpr = exports.HasAttributeExpr = exports.ObjectLiteralExpr = exports.StringLiteralExpr = exports.NumberLiteralExpr = exports.BooleanLiteralExpr = exports.NullLiteralExpr = exports.LiteralExpr = exports.VarExpr = exports.Expr = exports.ExprScope = exports.isJsonExpr = exports.ExprDependencies = void 0; | ||
exports.InterpolateExpr = exports.StepExpr = exports.CaseExpr = exports.MatchExpr = exports.LookupExpr = exports.CallExpr = exports.HasAttributeExpr = exports.ObjectLiteralExpr = exports.StringLiteralExpr = exports.NumberLiteralExpr = exports.BooleanLiteralExpr = exports.NullLiteralExpr = exports.LiteralExpr = exports.VarExpr = exports.Expr = exports.ExprScope = exports.isJsonExpr = exports.ExprDependencies = void 0; | ||
/* | ||
* Copyright (C) 2019-2021 HERE Europe B.V. | ||
* Licensed under Apache 2.0, see full license in LICENSE | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
const THREE = require("three"); | ||
@@ -27,2 +27,3 @@ const ExprEvaluator_1 = require("./ExprEvaluator"); | ||
const RGBA_1 = require("./RGBA"); | ||
const Theme_1 = require("./Theme"); | ||
__exportStar(require("./Env"), exports); | ||
@@ -33,2 +34,3 @@ const exprEvaluator = new ExprEvaluator_1.ExprEvaluator(); | ||
* The dependencies of an {@link Expr}. | ||
* @internal | ||
*/ | ||
@@ -104,2 +106,6 @@ class ExprDependencies { | ||
} | ||
visitLookupExpr(expr, context) { | ||
// Same behaviour as call expressions. | ||
return this.visitCallExpr(expr, context); | ||
} | ||
visitMatchExpr(expr, context) { | ||
@@ -134,2 +140,3 @@ expr.value.accept(this, context); | ||
* The evaluation scope of an {@link Expr}. | ||
* @internal | ||
*/ | ||
@@ -261,2 +268,3 @@ var ExprScope; | ||
* A node representing a `get` expression. | ||
* @internal | ||
*/ | ||
@@ -280,2 +288,3 @@ class VarExpr extends Expr { | ||
* A node representing a `literal` expression. | ||
* @internal | ||
*/ | ||
@@ -310,2 +319,3 @@ class LiteralExpr extends Expr { | ||
* Null literal expression. | ||
* @internal | ||
*/ | ||
@@ -331,2 +341,3 @@ class NullLiteralExpr extends LiteralExpr { | ||
* Boolean literal expression. | ||
* @internal | ||
*/ | ||
@@ -346,2 +357,3 @@ class BooleanLiteralExpr extends LiteralExpr { | ||
* Number literal expression. | ||
* @internal | ||
*/ | ||
@@ -361,2 +373,3 @@ class NumberLiteralExpr extends LiteralExpr { | ||
* String literal expression. | ||
* @internal | ||
*/ | ||
@@ -386,2 +399,3 @@ class StringLiteralExpr extends LiteralExpr { | ||
* Object literal expression. | ||
* @internal | ||
*/ | ||
@@ -404,2 +418,3 @@ class ObjectLiteralExpr extends LiteralExpr { | ||
* A node reperesenting a `has` expression. | ||
* @internal | ||
*/ | ||
@@ -423,2 +438,3 @@ class HasAttributeExpr extends Expr { | ||
* A node representing a `call` expression. | ||
* @internal | ||
*/ | ||
@@ -455,3 +471,50 @@ class CallExpr extends Expr { | ||
/** | ||
* A `lookup` expression is a call expression using the `lookup` operator. Then only difference is | ||
* that the lookup table definition (first argument) is cached as a map for fast search | ||
* (see {@link ExprEvaluator.visitLookupExpr}). | ||
* @internal | ||
*/ | ||
class LookupExpr extends CallExpr { | ||
/** | ||
* Constructs a LookupExpr instance. | ||
* @param args Arguments of the lookup expression. At least an argument for the lookup table. | ||
*/ | ||
constructor(args) { | ||
super("lookup", args); | ||
this.args = args; | ||
} | ||
/** | ||
* Creates a lookup expression from a {@link JsonArray}. | ||
* @param node The {@link JsonArray} to parse. | ||
* @param referenceResolverState Used to resolve references to definitions. | ||
* @returns A LookupExpr instance. | ||
*/ | ||
static parseArray(node, referenceResolverState) { | ||
const lookupTableNode = node[1]; | ||
if (lookupTableNode === undefined) { | ||
throw new Error("missing lookup table in 'lookup' expression"); | ||
} | ||
const lookupTableExpr = parseNode(lookupTableNode, referenceResolverState); | ||
if (!Array.isArray(lookupTableNode) || !(lookupTableExpr instanceof ObjectLiteralExpr)) { | ||
throw new Error(`Invalid lookup table expression for operator 'lookup'. It must be a literal or a ref to one.`); | ||
} | ||
const lookupTable = lookupTableExpr.value; | ||
if (!Array.isArray(lookupTable)) { | ||
throw new Error(`Invalid lookup table type (${typeof lookupTable}) for operator 'lookup'`); | ||
} | ||
// Skip the operator name and the lookup table and parse the rest of the arguments. Then add | ||
// the lookup table expr as first argument. | ||
const args = node.slice(2).map(childExpr => parseNode(childExpr, referenceResolverState)); | ||
args.unshift(lookupTableExpr); | ||
return new LookupExpr(args); | ||
} | ||
/** @override */ | ||
accept(visitor, context) { | ||
return visitor.visitLookupExpr(this, context); | ||
} | ||
} | ||
exports.LookupExpr = LookupExpr; | ||
/** | ||
* A node representing a `match` expression. | ||
* @internal | ||
*/ | ||
@@ -502,2 +565,3 @@ class MatchExpr extends Expr { | ||
* A node representing a `case` expression. | ||
* @internal | ||
*/ | ||
@@ -523,2 +587,3 @@ class CaseExpr extends Expr { | ||
* A node representing a `step` expression. | ||
* @internal | ||
*/ | ||
@@ -546,2 +611,3 @@ class StepExpr extends Expr { | ||
* A node representing an `interpolate` expression. | ||
* @internal | ||
*/ | ||
@@ -607,2 +673,6 @@ class InterpolateExpr extends Expr { | ||
} | ||
visitLookupExpr(expr, context) { | ||
// Same serialization as call expressions. | ||
return this.visitCallExpr(expr, context); | ||
} | ||
visitMatchExpr(expr, context) { | ||
@@ -685,2 +755,4 @@ const branches = []; | ||
return parseStepExpr(node, referenceResolverState); | ||
case "lookup": | ||
return LookupExpr.parseArray(node, referenceResolverState); | ||
default: | ||
@@ -830,12 +902,13 @@ return makeCallExpr(op, node, referenceResolverState); | ||
let result; | ||
if (InterpolatedPropertyDefs_1.isInterpolatedPropertyDefinition(definitionEntry.value)) { | ||
const definitionValue = Theme_1.getDefinitionValue(definitionEntry); | ||
if (InterpolatedPropertyDefs_1.isInterpolatedPropertyDefinition(definitionValue)) { | ||
// found a reference to an interpolation using | ||
// the deprecated object-like syntax. | ||
return Expr.fromJSON(InterpolatedPropertyDefs_1.interpolatedPropertyDefinitionToJsonExpr(definitionEntry.value)); | ||
return Expr.fromJSON(InterpolatedPropertyDefs_1.interpolatedPropertyDefinitionToJsonExpr(definitionEntry)); | ||
} | ||
else if (isJsonExpr(definitionEntry.value)) { | ||
definitionEntry = definitionEntry.value; | ||
else if (isJsonExpr(definitionValue)) { | ||
definitionEntry = definitionValue; | ||
} | ||
else { | ||
return Expr.fromJSON(definitionEntry.value); | ||
return Expr.fromJSON(definitionValue); | ||
} | ||
@@ -842,0 +915,0 @@ if (isJsonExpr(definitionEntry)) { |
@@ -1,2 +0,2 @@ | ||
import { BooleanLiteralExpr, CallExpr, CaseExpr, Env, Expr, ExprScope, ExprVisitor, HasAttributeExpr, InterpolateExpr, MatchExpr, NullLiteralExpr, NumberLiteralExpr, ObjectLiteralExpr, StepExpr, StringLiteralExpr, Value, VarExpr } from "./Expr"; | ||
import { BooleanLiteralExpr, CallExpr, CaseExpr, Env, Expr, ExprScope, ExprVisitor, HasAttributeExpr, InterpolateExpr, LookupExpr, MatchExpr, NullLiteralExpr, NumberLiteralExpr, ObjectLiteralExpr, StepExpr, StringLiteralExpr, Value, VarExpr } from "./Expr"; | ||
export interface OperatorDescriptor { | ||
@@ -61,2 +61,3 @@ /** | ||
visitCallExpr(expr: CallExpr, context: ExprEvaluatorContext): Value; | ||
visitLookupExpr(expr: LookupExpr, context: ExprEvaluatorContext): Value; | ||
visitStepExpr(expr: StepExpr, context: ExprEvaluatorContext): Value; | ||
@@ -63,0 +64,0 @@ visitInterpolateExpr(expr: InterpolateExpr, context: ExprEvaluatorContext): Value; |
@@ -288,2 +288,6 @@ "use strict"; | ||
} | ||
visitLookupExpr(expr, context) { | ||
// Same behaviour as call expressions. | ||
return this.visitCallExpr(expr, context); | ||
} | ||
visitStepExpr(expr, context) { | ||
@@ -290,0 +294,0 @@ if (context.scope === Expr_1.ExprScope.Value) { |
import { Env } from "./Env"; | ||
import { BooleanLiteralExpr, CallExpr, CaseExpr, Expr, ExprVisitor, HasAttributeExpr, InterpolateExpr, MatchExpr, NullLiteralExpr, NumberLiteralExpr, ObjectLiteralExpr, StepExpr, StringLiteralExpr, VarExpr } from "./Expr"; | ||
import { BooleanLiteralExpr, CallExpr, CaseExpr, Expr, ExprVisitor, HasAttributeExpr, InterpolateExpr, LookupExpr, MatchExpr, NullLiteralExpr, NumberLiteralExpr, ObjectLiteralExpr, StepExpr, StringLiteralExpr, VarExpr } from "./Expr"; | ||
export interface InstantiationContext { | ||
@@ -24,3 +24,5 @@ /** | ||
visitHasAttributeExpr(expr: HasAttributeExpr, context: InstantiationContext): Expr; | ||
private visitCallExprImpl; | ||
visitCallExpr(expr: CallExpr, context: InstantiationContext): Expr; | ||
visitLookupExpr(expr: LookupExpr, context: InstantiationContext): Expr; | ||
visitMatchExpr(match: MatchExpr, context: InstantiationContext): Expr; | ||
@@ -27,0 +29,0 @@ visitCaseExpr(expr: CaseExpr, context: InstantiationContext): Expr; |
@@ -45,9 +45,19 @@ "use strict"; | ||
} | ||
visitCallExpr(expr, context) { | ||
visitCallExprImpl(expr, context, constructor) { | ||
const args = expr.args.map(arg => arg.accept(this, context)); | ||
if (args.some((a, i) => a !== expr.args[i])) { | ||
return new Expr_1.CallExpr(expr.op, args); | ||
return constructor(expr.op, args); | ||
} | ||
return expr; | ||
} | ||
visitCallExpr(expr, context) { | ||
return this.visitCallExprImpl(expr, context, (op, args) => { | ||
return new Expr_1.CallExpr(op, args); | ||
}); | ||
} | ||
visitLookupExpr(expr, context) { | ||
return this.visitCallExprImpl(expr, context, (op, args) => { | ||
return new Expr_1.LookupExpr(args); | ||
}); | ||
} | ||
visitMatchExpr(match, context) { | ||
@@ -54,0 +64,0 @@ const value = match.value.accept(this, context); |
@@ -1,2 +0,2 @@ | ||
import { BooleanLiteralExpr, CallExpr, CaseExpr, Expr, ExprVisitor, HasAttributeExpr, InterpolateExpr, MatchExpr, NullLiteralExpr, NumberLiteralExpr, ObjectLiteralExpr, StepExpr, StringLiteralExpr, VarExpr } from "./Expr"; | ||
import { BooleanLiteralExpr, CallExpr, CaseExpr, Expr, ExprVisitor, HasAttributeExpr, InterpolateExpr, LookupExpr, MatchExpr, NullLiteralExpr, NumberLiteralExpr, ObjectLiteralExpr, StepExpr, StringLiteralExpr, VarExpr } from "./Expr"; | ||
/** | ||
@@ -37,3 +37,5 @@ * [[ExprPool]] maintains a set of unique interned {@link Expr} objects. | ||
visitCaseExpr(expr: CaseExpr, context: void): Expr; | ||
private visitCallExprImpl; | ||
visitCallExpr(expr: CallExpr, context: void): Expr; | ||
visitLookupExpr(expr: LookupExpr, context: void): Expr; | ||
visitStepExpr(expr: StepExpr, context: void): Expr; | ||
@@ -40,0 +42,0 @@ visitInterpolateExpr(expr: InterpolateExpr, context: void): Expr; |
@@ -167,3 +167,3 @@ "use strict"; | ||
} | ||
visitCallExpr(expr, context) { | ||
visitCallExprImpl(expr, context, constructor) { | ||
// rewrite the actual arguments | ||
@@ -194,3 +194,3 @@ const expressions = expr.args.map(childExpr => childExpr.accept(this, context)); | ||
} | ||
const e = new Expr_1.CallExpr(expr.op, expressions); | ||
const e = constructor(expr.op, expressions); | ||
e.descriptor = expr.descriptor; | ||
@@ -200,2 +200,12 @@ calls.push(e); | ||
} | ||
visitCallExpr(expr, context) { | ||
return this.visitCallExprImpl(expr, context, (op, args) => { | ||
return new Expr_1.CallExpr(op, args); | ||
}); | ||
} | ||
visitLookupExpr(expr, context) { | ||
return this.visitCallExprImpl(expr, context, (op, args) => { | ||
return new Expr_1.LookupExpr(args); | ||
}); | ||
} | ||
visitStepExpr(expr, context) { | ||
@@ -202,0 +212,0 @@ if (this.m_stepExprs.includes(expr)) { |
@@ -1,3 +0,6 @@ | ||
import { CallExpr } from "../Expr"; | ||
import { CallExpr, LookupExpr, Value } from "../Expr"; | ||
import { ExprEvaluatorContext, OperatorDescriptorMap } from "../ExprEvaluator"; | ||
interface KeyValObj { | ||
[key: string]: Value; | ||
} | ||
declare const operators: { | ||
@@ -8,4 +11,7 @@ length: { | ||
coalesce: { | ||
call: (context: ExprEvaluatorContext, call: CallExpr) => import("../Env").Value; | ||
call: (context: ExprEvaluatorContext, call: CallExpr) => Value; | ||
}; | ||
lookup: { | ||
call: (context: ExprEvaluatorContext, lookup: LookupExpr) => KeyValObj | null; | ||
}; | ||
}; | ||
@@ -12,0 +18,0 @@ export declare const MiscOperators: OperatorDescriptorMap; |
@@ -9,2 +9,104 @@ "use strict"; | ||
exports.MiscOperators = void 0; | ||
const harp_utils_1 = require("@here/harp-utils"); | ||
const Expr_1 = require("../Expr"); | ||
function joinKeyValues(keys) { | ||
return keys.join("&"); | ||
} | ||
function stringifyKeyValue(key, value) { | ||
return key + "=" + JSON.stringify(value); | ||
} | ||
/** | ||
* Joins the strings of each given array. | ||
* @param combinations Array of string arrays that must be joined. | ||
* @returns The joined strings sorted from longest to shortest (in number of substrings). | ||
*/ | ||
function joinCombinations(combinations) { | ||
// sort from longest (more specific) to shortest (more generic). | ||
combinations.sort((lhs, rhs) => rhs.length - lhs.length); | ||
const result = combinations.map((keys) => joinKeyValues(keys)); | ||
// Add the empty combination which will match a default table entry (an entry without keys) if | ||
// it exists. | ||
result.push(""); | ||
return result; | ||
} | ||
/** | ||
* Gets all combinations of all lengths of a list of strings. | ||
* @param input An array containing all strings. | ||
* @param index Start index of the strings in `input` that will be considered. | ||
* @returns An array of all combinations. The strings within each combination are in the inverse | ||
* order of the input array. | ||
*/ | ||
function getAllCombinations(input, index = 0) { | ||
if (index >= input.length) { | ||
return []; | ||
} | ||
const combinations = getAllCombinations(input, index + 1); | ||
const initLength = combinations.length; | ||
for (let i = 0; i < initLength; i += 1) { | ||
combinations.push([...combinations[i], input[index]]); | ||
} | ||
combinations.push([input[index]]); | ||
return combinations; | ||
} | ||
/** | ||
* Make all combinations of all lengths with the search keys of the given lookup expression. | ||
* @param lookupExpr The lookup expression. | ||
* @param context The context to evaluate expressions. | ||
* @returns All combinations, sorted from longest(more specific) to shortest (more generic). | ||
*/ | ||
function getKeyCombinations(lookupExpr, context) { | ||
const keys = lookupExpr.args.slice(1); | ||
const result = []; | ||
for (let i = 0; i < keys.length; i += 2) { | ||
const value = context.evaluate(keys[i + 1]); | ||
// ignore keys whose values evaluate to null. | ||
if (value === null) { | ||
continue; | ||
} | ||
const key = context.evaluate(keys[i]); | ||
result.push(stringifyKeyValue(key, value)); | ||
} | ||
// Reverse sort, getAllCombinations reverses the order. | ||
result.sort().reverse(); | ||
return joinCombinations(getAllCombinations(result)); | ||
} | ||
/** | ||
* Creates a map from the lookup entries in a given array. | ||
* @param lookupArray The array to transform. | ||
* @returns The resulting map. | ||
*/ | ||
function createLookupMap(lookupArray) { | ||
const map = new Map(); | ||
for (const entry of lookupArray) { | ||
if (typeof entry !== "object") { | ||
throw new Error(`Invalid lookup table entry type (${typeof entry})`); | ||
} | ||
if (!entry.keys) { | ||
throw new Error(`Lookup table entry has no 'keys' property.`); | ||
} | ||
if (!entry.attributes) { | ||
throw new Error(`Lookup table entry has no 'attributes' property.`); | ||
} | ||
const key = joinKeyValues(Object.getOwnPropertyNames(entry.keys) | ||
.sort() | ||
.map(key => stringifyKeyValue(key, entry.keys[key]))); | ||
map.set(key, entry.attributes); | ||
} | ||
return map; | ||
} | ||
/** | ||
* Searches matches of the given keys in a map. | ||
* @param keys Keys to search in the map. | ||
* @param map The lookup map. | ||
* @returns The first match (in the order in which keys are given) or null if no match found. | ||
*/ | ||
function searchLookupMap(keys, map) { | ||
for (const key of keys) { | ||
const matchAttributes = map.get(key); | ||
if (matchAttributes) { | ||
return matchAttributes; | ||
} | ||
} | ||
return null; | ||
} | ||
const operators = { | ||
@@ -30,2 +132,21 @@ length: { | ||
} | ||
}, | ||
lookup: { | ||
call: (context, lookup) => { | ||
// Argument types are checked on parsing, see LookupExpr.parseArray(). | ||
harp_utils_1.assert(lookup.args.length > 0, "missing lookup table"); | ||
const keyCombinations = getKeyCombinations(lookup, context); | ||
let table = context.evaluate(lookup.args[0]); | ||
harp_utils_1.assert(Array.isArray(table) || table instanceof Map, "wrong lookup table type"); | ||
if (Array.isArray(table)) { | ||
// Transform the lookup table into a map to speedup lookup, since the same table | ||
// might be used by multiple lookup expressions. | ||
table = createLookupMap(table); | ||
const lookupMapExpr = new Expr_1.ObjectLiteralExpr(table); | ||
// Replace the lookup table argument with the map. Next calls to the same expression | ||
// (e.g. re-evaluations due to data dependencies) will use the map. | ||
lookup.args[0] = lookupMapExpr; | ||
} | ||
return searchLookupMap(keyCombinations, table); | ||
} | ||
} | ||
@@ -32,0 +153,0 @@ }; |
@@ -115,8 +115,2 @@ import { Env, Expr, Value } from "./Expr"; | ||
/** | ||
* Get the expression evaluation cache, for further feature processing. | ||
* | ||
* This object is valid until next `getMatchingTechniques` call. | ||
*/ | ||
get expressionEvaluatorCache(): Map<Expr, Value>; | ||
/** | ||
* Reset array of techniques. | ||
@@ -123,0 +117,0 @@ * |
@@ -5,3 +5,3 @@ "use strict"; | ||
/* | ||
* Copyright (C) 2019-2021 HERE Europe B.V. | ||
* Copyright (C) 2019-2022 HERE Europe B.V. | ||
* Licensed under Apache 2.0, see full license in LICENSE | ||
@@ -117,2 +117,5 @@ * SPDX-License-Identifier: Apache-2.0 | ||
} | ||
visitLookupExpr(lookup, enclosingExpr) { | ||
return this.visitCallExpr(lookup, enclosingExpr); | ||
} | ||
visitStepExpr(expr, enclosingExpr) { | ||
@@ -276,10 +279,2 @@ return expr; | ||
/** | ||
* Get the expression evaluation cache, for further feature processing. | ||
* | ||
* This object is valid until next `getMatchingTechniques` call. | ||
*/ | ||
get expressionEvaluatorCache() { | ||
return this.m_cachedResults; | ||
} | ||
/** | ||
* Reset array of techniques. | ||
@@ -374,6 +369,6 @@ * | ||
if (Expr_1.isJsonExpr(style.minZoomLevel)) { | ||
style._minZoomLevelExpr = Expr_1.Expr.fromJSON(style.minZoomLevel).intern(this.m_exprPool); | ||
style._minZoomLevelExpr = Expr_1.Expr.fromJSON(style.minZoomLevel, this.m_definitions).intern(this.m_exprPool); | ||
} | ||
if (Expr_1.isJsonExpr(style.maxZoomLevel)) { | ||
style._maxZoomLevelExpr = Expr_1.Expr.fromJSON(style.maxZoomLevel).intern(this.m_exprPool); | ||
style._maxZoomLevelExpr = Expr_1.Expr.fromJSON(style.maxZoomLevel, this.m_definitions).intern(this.m_exprPool); | ||
} | ||
@@ -380,0 +375,0 @@ } |
@@ -21,3 +21,3 @@ import { Vector3Like } from "@here/harp-geoutils/lib/math/Vector3Like"; | ||
*/ | ||
extends?: string | Theme | Array<string | Theme>; | ||
extends?: string | Theme | FlatTheme | Array<string | Theme | FlatTheme>; | ||
/** | ||
@@ -90,3 +90,3 @@ * Actual URL the theme has been loaded from. | ||
* | ||
* @example | ||
* | ||
* ```json | ||
@@ -117,3 +117,2 @@ * { | ||
* | ||
* @example | ||
* ```json | ||
@@ -165,3 +164,8 @@ * { | ||
*/ | ||
export interface Definition { | ||
export declare type Definition = JsonValue | InterpolatedPropertyDefinition<JsonValue>; | ||
/** | ||
* This is the old, more verbose, format of the definitions, to be deprecated | ||
* @deprecated | ||
*/ | ||
export interface VerboseDefinition { | ||
/** | ||
@@ -174,3 +178,3 @@ * The type of the definition. | ||
*/ | ||
value: JsonValue | InterpolatedPropertyDefinition<JsonValue>; | ||
value: Definition; | ||
/** | ||
@@ -182,6 +186,21 @@ * The description of the definition. | ||
/** | ||
* An set of {@link Definition}s. | ||
* This is to distinguish between definition types at runtime, to be deprecated with | ||
* {@link VerboseDefinition} | ||
* @deprecated | ||
* | ||
* @param definition | ||
* @returns `true` if the Definition is of the deprecated {@link VerboseDefinition} type | ||
*/ | ||
export declare function isVerboseDefinition(definition: VerboseDefinition | Definition): boolean; | ||
/** | ||
* This is a utility function to retrive a definitions value until {@link VerboseDefinition} is fully | ||
* deprecated | ||
* @deprecated | ||
* | ||
* @param definition | ||
* @returns value of the given definition. | ||
*/ | ||
export declare function getDefinitionValue(definition: VerboseDefinition | Definition): Definition; | ||
export interface Definitions { | ||
[name: string]: Definition; | ||
[name: string]: Definition | VerboseDefinition; | ||
} | ||
@@ -296,2 +315,5 @@ export declare type JsonExprReference = ["ref", string]; | ||
debug?: boolean; | ||
/** | ||
* @deprecated Technique parameters are now properties at the Style interface level. | ||
*/ | ||
attr?: Partial<Params>; | ||
@@ -316,3 +338,3 @@ } | ||
* "definitions": { | ||
* "roadColor": { "type": "color", "value": "#f00" } | ||
* "roadColor": "#f00" | ||
* }, | ||
@@ -319,0 +341,0 @@ * "styles": { "tilezen": [ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isJsonExprReference = void 0; | ||
exports.isJsonExprReference = exports.getDefinitionValue = exports.isVerboseDefinition = void 0; | ||
/** | ||
* This is to distinguish between definition types at runtime, to be deprecated with | ||
* {@link VerboseDefinition} | ||
* @deprecated | ||
* | ||
* @param definition | ||
* @returns `true` if the Definition is of the deprecated {@link VerboseDefinition} type | ||
*/ | ||
function isVerboseDefinition(definition) { | ||
var _a; | ||
return ((_a = definition) === null || _a === void 0 ? void 0 : _a.value) !== undefined; | ||
} | ||
exports.isVerboseDefinition = isVerboseDefinition; | ||
/** | ||
* This is a utility function to retrive a definitions value until {@link VerboseDefinition} is fully | ||
* deprecated | ||
* @deprecated | ||
* | ||
* @param definition | ||
* @returns value of the given definition. | ||
*/ | ||
function getDefinitionValue(definition) { | ||
return isVerboseDefinition(definition) | ||
? definition.value | ||
: definition; | ||
} | ||
exports.getDefinitionValue = getDefinitionValue; | ||
/** | ||
* Checks if the given value is a reference to a definition. | ||
@@ -6,0 +33,0 @@ * |
{ | ||
"name": "@here/harp-datasource-protocol", | ||
"version": "0.27.1", | ||
"version": "0.28.0", | ||
"description": "Components used for the decoding and styling of data that is used by the Datasources.", | ||
@@ -14,3 +14,3 @@ "main": "index.js", | ||
"prepare": "cross-env tsc --build $EXTRA_TSC_ARGS", | ||
"generate-json-schema": "ts-json-schema-generator --no-type-check --path ./lib/Theme.ts --type Theme --validationKeywords defaultSnippets > theme.schema.json" | ||
"generate-json-schema": "typeconv -f ts -t jsc ./lib/Theme.ts && cp ./lib/Theme.json theme.schema.json && rm ./lib/Theme.json " | ||
}, | ||
@@ -28,9 +28,9 @@ "repository": { | ||
"dependencies": { | ||
"@here/harp-geometry": "^0.27.1", | ||
"@here/harp-geoutils": "^0.27.1", | ||
"@here/harp-utils": "^0.27.1", | ||
"@here/harp-geometry": "^0.28.0", | ||
"@here/harp-geoutils": "^0.28.0", | ||
"@here/harp-utils": "^0.28.0", | ||
"csscolorparser": "^1.0.3" | ||
}, | ||
"devDependencies": { | ||
"@here/harp-test-utils": "^0.27.1", | ||
"@here/harp-test-utils": "^0.28.0", | ||
"@types/chai": "^4.2.14", | ||
@@ -44,3 +44,3 @@ "@types/mocha": "^8.2.0", | ||
"three": "^0.129.0", | ||
"ts-json-schema-generator": "^0.68.1", | ||
"typeconv": "^1.7.0", | ||
"typescript": "^4.1.2" | ||
@@ -54,3 +54,3 @@ }, | ||
}, | ||
"gitHead": "6c17056d057918bdbf3599bac350b8298a95ff1f" | ||
"gitHead": "e55351c399672d382cdaefdd8a3c20cce29c024b" | ||
} |
@@ -556,2 +556,105 @@ # Style Expressions | ||
## lookup | ||
Returns the entry's attributes in the `lookupTable` that matches the whole | ||
or a subset of the given key values. The match with the highest specificity | ||
(i.e. the match with highest number of matching key values) is returned. | ||
If there is more than a match with the same highest specificity (i.e. the same | ||
number of key-values) then there is no guarantee which of these matches will be returned. | ||
If `lookupTable` has a default entry, meaning entry with zero | ||
keys, then if no match is found the default entry's attributes are returned. | ||
If no match is found and no default entry is defined in `lookupTable`, then null is returned. | ||
Requirements: | ||
- keys have to be strings | ||
- lookupTable should be a literal expression or a ref expression pointing to a literal. | ||
Additionally: the structure of a literal is an array of objects. | ||
Each object has to contain "keys" member and "attributes" member. | ||
The value of keys is an object with key=value pairs. The value of attributes is an arbitrary | ||
JSON value and is returned from the lookup function when all keys match as described above. | ||
```javascript | ||
["lookup", | ||
lookuptable, | ||
key1, value1, | ||
... | ||
keyN, valueN | ||
] | ||
``` | ||
Example: | ||
```javascript | ||
{ | ||
"definitions": { | ||
"poi_table_here": { // this is the lookup table | ||
"value": [ | ||
"literal", | ||
[ | ||
{ | ||
"keys": { | ||
"pdsId": "100-1000-0000", | ||
"isoCountryCode": "JPN" | ||
}, | ||
"attributes": { | ||
"iconNextToEachOther": "no", | ||
"iconName": "eatdrink_main", // different name for Japan | ||
"priority": 264, | ||
} | ||
}, | ||
{ | ||
"keys": { | ||
"pdsId": "100-1000-0000" | ||
}, | ||
"attributes": { | ||
"iconNextToEachOther": "no", | ||
"iconName": "eatdrink_restaurant", | ||
"priority": 264, | ||
} | ||
}, | ||
... | ||
{ // default entry | ||
"keys": {}, | ||
"attributes": { | ||
"iconNextToEachOther": "no", | ||
"iconName": "default", | ||
"priority": 0, | ||
} | ||
} | ||
] | ||
] | ||
} | ||
} | ||
} | ||
[ | ||
"lookup", | ||
["ref", "poi_table_here"], // lookupTable | ||
"pdsId", "100-1000-0000", | ||
"isoCountryCode", "JPN" | ||
] // returns the first entry's attributes | ||
[ | ||
"get", | ||
"iconName", | ||
[ | ||
"lookup", // expression name | ||
["ref","poi_table_here"], // lookupTable | ||
"pdsId", "100-1000-0000", | ||
"isoCountryCode", "JPN" | ||
] | ||
] // returns "eatdrink_main" | ||
[ | ||
"get", | ||
"iconName", | ||
[ | ||
"lookup", // expression name | ||
["ref","poi_table_here"], // lookupTable | ||
"isoCountryCode", "NoCountryName" // this key value will not match anything | ||
] | ||
] // returns "default" | ||
``` | ||
## Math operators | ||
@@ -558,0 +661,0 @@ |
Sorry, the diff of this file is too big to display
470299
12138
+ Added@here/harp-geometry@0.28.0(transitive)
+ Added@here/harp-geoutils@0.28.0(transitive)
+ Added@here/harp-utils@0.28.0(transitive)
- Removed@here/harp-geometry@0.27.1(transitive)
- Removed@here/harp-geoutils@0.27.1(transitive)
- Removed@here/harp-utils@0.27.1(transitive)
Updated@here/harp-geometry@^0.28.0
Updated@here/harp-geoutils@^0.28.0
Updated@here/harp-utils@^0.28.0