@player-ui/player 0.3.0-next.3 → 0.3.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/index.cjs.js +4128 -891
  2. package/dist/index.d.ts +1227 -50
  3. package/dist/index.esm.js +4065 -836
  4. package/package.json +9 -15
  5. package/src/binding/binding.ts +108 -0
  6. package/src/binding/index.ts +188 -0
  7. package/src/binding/resolver.ts +157 -0
  8. package/src/binding/utils.ts +51 -0
  9. package/src/binding-grammar/ast.ts +113 -0
  10. package/src/binding-grammar/custom/index.ts +304 -0
  11. package/src/binding-grammar/ebnf/binding.ebnf +22 -0
  12. package/src/binding-grammar/ebnf/index.ts +186 -0
  13. package/src/binding-grammar/ebnf/types.ts +104 -0
  14. package/src/binding-grammar/index.ts +4 -0
  15. package/src/binding-grammar/parsimmon/index.ts +78 -0
  16. package/src/controllers/constants/index.ts +85 -0
  17. package/src/controllers/constants/utils.ts +37 -0
  18. package/src/{data.ts → controllers/data.ts} +6 -6
  19. package/src/controllers/flow/controller.ts +95 -0
  20. package/src/controllers/flow/flow.ts +205 -0
  21. package/src/controllers/flow/index.ts +2 -0
  22. package/src/controllers/index.ts +5 -0
  23. package/src/{validation → controllers/validation}/binding-tracker.ts +5 -5
  24. package/src/{validation → controllers/validation}/controller.ts +15 -14
  25. package/src/{validation → controllers/validation}/index.ts +0 -0
  26. package/src/{view → controllers/view}/asset-transform.ts +2 -3
  27. package/src/{view → controllers/view}/controller.ts +9 -8
  28. package/src/controllers/view/index.ts +4 -0
  29. package/src/{view → controllers/view}/store.ts +0 -0
  30. package/src/{view → controllers/view}/types.ts +2 -1
  31. package/src/data/dependency-tracker.ts +187 -0
  32. package/src/data/index.ts +4 -0
  33. package/src/data/local-model.ts +41 -0
  34. package/src/data/model.ts +216 -0
  35. package/src/data/noop-model.ts +18 -0
  36. package/src/expressions/evaluator-functions.ts +29 -0
  37. package/src/expressions/evaluator.ts +405 -0
  38. package/src/expressions/index.ts +3 -0
  39. package/src/expressions/parser.ts +889 -0
  40. package/src/expressions/types.ts +200 -0
  41. package/src/expressions/utils.ts +8 -0
  42. package/src/index.ts +9 -12
  43. package/src/logger/consoleLogger.ts +49 -0
  44. package/src/logger/index.ts +5 -0
  45. package/src/logger/noopLogger.ts +13 -0
  46. package/src/logger/proxyLogger.ts +25 -0
  47. package/src/logger/tapableLogger.ts +38 -0
  48. package/src/logger/types.ts +6 -0
  49. package/src/player.ts +21 -18
  50. package/src/plugins/flow-exp-plugin.ts +2 -3
  51. package/src/schema/index.ts +2 -0
  52. package/src/schema/schema.ts +220 -0
  53. package/src/schema/types.ts +60 -0
  54. package/src/string-resolver/index.ts +188 -0
  55. package/src/types.ts +11 -13
  56. package/src/utils/index.ts +1 -0
  57. package/src/utils/replaceParams.ts +17 -0
  58. package/src/validator/index.ts +3 -0
  59. package/src/validator/registry.ts +20 -0
  60. package/src/validator/types.ts +75 -0
  61. package/src/validator/validation-middleware.ts +114 -0
  62. package/src/view/builder/index.ts +81 -0
  63. package/src/view/index.ts +5 -4
  64. package/src/view/parser/index.ts +318 -0
  65. package/src/view/parser/types.ts +141 -0
  66. package/src/view/plugins/applicability.ts +78 -0
  67. package/src/view/plugins/index.ts +5 -0
  68. package/src/view/plugins/options.ts +4 -0
  69. package/src/view/plugins/plugin.ts +21 -0
  70. package/src/view/plugins/string-resolver.ts +149 -0
  71. package/src/view/plugins/switch.ts +120 -0
  72. package/src/view/plugins/template-plugin.ts +172 -0
  73. package/src/view/resolver/index.ts +397 -0
  74. package/src/view/resolver/types.ts +161 -0
  75. package/src/view/resolver/utils.ts +57 -0
  76. package/src/view/view.ts +149 -0
  77. package/src/utils/desc.d.ts +0 -2
package/dist/index.d.ts CHANGED
@@ -1,64 +1,1047 @@
1
1
  import * as _player_ui_types from '@player-ui/types';
2
- import { Asset, Validation, Flow, FlowResult, NavigationFlowViewState, View } from '@player-ui/types';
2
+ import { Formatting, NavigationFlowState, NavigationFlow, NavigationFlowEndState, Navigation, Asset, Expression, Binding, Schema, Validation, View as View$1, Flow, FlowResult, NavigationFlowViewState } from '@player-ui/types';
3
3
  export * from '@player-ui/types';
4
- import { BindingInstance, BindingFactory, BindingParser, BindingLike } from '@player-ui/binding';
5
- export * from '@player-ui/binding';
6
- import { DataModelMiddleware, DataModelWithParser, DataModelOptions, DataPipeline, BatchSetTransaction, Updates, PipelinedDataModel } from '@player-ui/data';
7
- export * from '@player-ui/data';
8
- import { ExpressionEvaluator } from '@player-ui/expressions';
9
- export * from '@player-ui/expressions';
10
- import { FlowController } from '@player-ui/flow';
11
- export * from '@player-ui/flow';
12
- import { Logger, TapableLogger } from '@player-ui/logger';
13
- export * from '@player-ui/logger';
14
- import { SchemaController } from '@player-ui/schema';
15
- export * from '@player-ui/schema';
16
- export * from '@player-ui/string-resolver';
17
- import * as _player_ui_validator from '@player-ui/validator';
18
- import { ValidatorRegistry, ValidationResponse, ValidatorContext, ValidationObject, WarningValidationResponse, ErrorValidationResponse } from '@player-ui/validator';
19
- export * from '@player-ui/validator';
20
- import { Node, Resolve, ViewPlugin, Resolver, ViewInstance } from '@player-ui/view';
21
- export * from '@player-ui/view';
22
- import { SyncHook, SyncWaterfallHook, SyncBailHook } from 'tapable-ts';
23
- import { ConstantsController } from '@player-ui/constants';
4
+ import { SyncBailHook, SyncWaterfallHook, SyncHook } from 'tapable-ts';
24
5
  import { Registry } from '@player-ui/partial-match-registry';
25
6
 
26
- interface Store {
27
- useLocalState<T>(initialState: T): readonly [T, (value: T) => void];
28
- useSharedState<T>(key: string | symbol): (initialState: T) => readonly [T, (value: T) => void];
7
+ interface Node$1<T extends string> {
8
+ /** The basic node type */
9
+ name: T;
29
10
  }
30
- interface SharedStore {
31
- getLocalStateFunction<T>(key: string | symbol, countKey: symbol): (initialState: T) => readonly [T, (value: T) => void];
32
- useSharedState<T>(key: string | symbol): (initialState: T) => readonly [T, (value: T) => void];
11
+ /**
12
+ * An AST node that represents a nested path in the model
13
+ * foo.{{bar}}.baz (this is {{bar}})
14
+ */
15
+ interface PathNode extends Node$1<'PathNode'> {
16
+ /** The path in the model that this node represents */
17
+ path: Array<AnyNode>;
33
18
  }
34
- /** A store that holds on to state for a transform */
35
- declare class LocalStateStore implements SharedStore {
36
- private state;
37
- private updateCallback?;
38
- constructor(onUpdate?: () => void);
39
- removeKey(key: symbol | string): void;
19
+ /**
20
+ * A segment representing a query
21
+ * [foo=bar]
22
+ */
23
+ interface QueryNode extends Node$1<'Query'> {
24
+ /** The key to query */
25
+ key: AnyNode;
26
+ /** The target value */
27
+ value?: AnyNode;
28
+ }
29
+ /** A simple segment */
30
+ interface ValueNode extends Node$1<'Value'> {
31
+ /** The segment value */
32
+ value: string | number;
33
+ }
34
+ /** A nested expression */
35
+ interface ExpressionNode$1 extends Node$1<'Expression'> {
36
+ /** The expression */
37
+ value: string;
38
+ }
39
+ /**
40
+ * A binding segment that's multiple smaller ones
41
+ * {{foo}}_bar_{{baz}}
42
+ */
43
+ interface ConcatenatedNode extends Node$1<'Concatenated'> {
44
+ /** A list of nested paths, or value nodes to concat together to form a segment */
45
+ value: Array<PathNode | ValueNode | ExpressionNode$1>;
46
+ }
47
+ declare type AnyNode = PathNode | QueryNode | ValueNode | ConcatenatedNode | ExpressionNode$1;
48
+
49
+ interface BindingParserOptions {
50
+ /** Get the value for a specific binding */
51
+ get: (binding: BindingInstance) => any;
52
+ /**
53
+ * Set the values for bindings.
54
+ * This is used when the query syntax needs to modify an object
55
+ */
56
+ set: (transaction: Array<[BindingInstance, any]>) => void;
57
+ /**
58
+ * Get the result of evaluating an expression
59
+ */
60
+ evaluate: (exp: string) => any;
61
+ }
62
+ declare type Getter = (path: BindingInstance) => any;
63
+ declare type RawBindingSegment = number | string;
64
+ declare type RawBinding = string | RawBindingSegment[];
65
+ declare type BindingLike = RawBinding | BindingInstance;
66
+ declare type BindingFactory = (raw: RawBinding, options?: Partial<BindingParserOptions>) => BindingInstance;
67
+ /**
68
+ * A path in the data model
69
+ */
70
+ declare class BindingInstance {
71
+ private split;
72
+ private joined;
73
+ private factory;
74
+ constructor(raw: RawBinding, factory?: (rawBinding: RawBinding) => BindingInstance);
75
+ asArray(): RawBindingSegment[];
76
+ asString(): string;
77
+ /**
78
+ * Check to see if the given binding is a sub-path of the current one
79
+ */
80
+ contains(binding: BindingInstance): boolean;
81
+ relative(binding: BindingInstance): RawBindingSegment[];
82
+ parent(): BindingInstance;
83
+ key(): RawBindingSegment;
84
+ /**
85
+ * This is a utility method to get a binding that is a descendent of this binding
86
+ *
87
+ * @param relative - The relative path to descend to
88
+ */
89
+ descendent(relative: BindingLike): BindingInstance;
90
+ }
91
+
92
+ interface NormalizedResult {
93
+ /** The normalized path */
94
+ path: Array<string | number>;
95
+ /** Any new updates that need to happen for this binding to be resolved */
96
+ updates?: Record<string, any>;
97
+ }
98
+ interface ResolveBindingASTOptions {
99
+ /** Get the value of the model at the given path */
100
+ getValue: (path: Array<string | number>) => any;
101
+ /** Convert the value into valid path segments */
102
+ convertToPath: (value: any) => string;
103
+ /** Convert the value into valid path segments */
104
+ evaluate: (exp: string) => any;
105
+ }
106
+
107
+ /** Check if the parameter representing a binding is already of the Binding class */
108
+ declare function isBinding(binding: BindingLike): binding is BindingInstance;
109
+ /** Convert the string to an int if you can, otherwise just return the original string */
110
+ declare function maybeConvertToNum(i: string): string | number;
111
+ /**
112
+ * utility to convert binding into binding segments.
113
+ */
114
+ declare function getBindingSegments(binding: BindingLike): Array<string | number>;
115
+ /** Like _.findIndex, but ignores types */
116
+ declare function findInArray<T extends Record<string | number, object>>(array: Array<T>, key: string | number, value: T): number | undefined;
117
+
118
+ declare const SIMPLE_BINDING_REGEX: RegExp;
119
+ /** A parser for creating bindings from a string */
120
+ declare class BindingParser {
121
+ private cache;
122
+ private parseCache;
123
+ private parserOptions;
124
+ hooks: {
125
+ skipOptimization: SyncBailHook<[string], boolean, Record<string, any>>;
126
+ beforeResolveNode: SyncWaterfallHook<[AnyNode, Required<NormalizedResult> & ResolveBindingASTOptions], Record<string, any>>;
127
+ };
128
+ constructor(options?: Partial<BindingParserOptions>);
129
+ /**
130
+ * Takes a binding path, parses it, and returns an equivalent, normalized
131
+ * representation of that path.
132
+ */
133
+ private normalizePath;
134
+ private getBindingForNormalizedResult;
135
+ parse(rawBinding: BindingLike, overrides?: Partial<BindingParserOptions>): BindingInstance;
136
+ }
137
+
138
+ declare const ROOT_BINDING: BindingInstance;
139
+ declare type BatchSetTransaction = [BindingInstance, any][];
140
+ declare type Updates = Array<{
141
+ /** The updated binding */
142
+ binding: BindingInstance;
143
+ /** The old value */
144
+ oldValue: any;
145
+ /** The new value */
146
+ newValue: any;
147
+ /** Force the Update to be included even if no data changed */
148
+ force?: boolean;
149
+ }>;
150
+ /** Options to use when getting or setting data */
151
+ interface DataModelOptions {
152
+ /**
153
+ * The data (either to set or get) should represent a formatted value
154
+ * For setting data, the data will be de-formatted before continuing in the pipeline
155
+ * For getting data, the data will be formatted before returning
156
+ */
157
+ formatted?: boolean;
158
+ /**
159
+ * By default, fetching data will ignore any invalid data.
160
+ * You can choose to grab the queued invalid data if you'd like
161
+ * This is usually the case for user-inputs
162
+ */
163
+ includeInvalid?: boolean;
164
+ /**
165
+ * A flag to set to ignore any default value in the schema, and just use the raw value
166
+ */
167
+ ignoreDefaultValue?: boolean;
168
+ /** Other context associated with this request */
169
+ context?: {
170
+ /** The data model to use when getting other data from the context of this request */
171
+ model: DataModelWithParser;
172
+ };
173
+ }
174
+ interface DataModelWithParser<Options = DataModelOptions> {
175
+ get(binding: BindingLike, options?: Options): any;
176
+ set(transaction: [BindingLike, any][], options?: Options): Updates;
177
+ }
178
+ interface DataModelImpl<Options = DataModelOptions> {
179
+ get(binding: BindingInstance, options?: Options): any;
180
+ set(transaction: BatchSetTransaction, options?: Options): Updates;
181
+ }
182
+ interface DataModelMiddleware {
183
+ /** The name of the middleware */
184
+ name?: string;
185
+ set(transaction: BatchSetTransaction, options?: DataModelOptions, next?: DataModelImpl): Updates;
186
+ get(binding: BindingInstance, options?: DataModelOptions, next?: DataModelImpl): any;
187
+ reset?(): void;
188
+ }
189
+ /** Wrap the inputs of the DataModel with calls to parse raw binding inputs */
190
+ declare function withParser<Options = unknown>(model: DataModelImpl<Options>, parseBinding: BindingFactory): DataModelWithParser<Options>;
191
+ /** Wrap a middleware instance in a DataModel compliant API */
192
+ declare function toModel(middleware: DataModelMiddleware, defaultOptions?: DataModelOptions, next?: DataModelImpl): DataModelImpl;
193
+ declare type DataPipeline = Array<DataModelMiddleware | DataModelImpl>;
194
+ /**
195
+ * Given a set of steps in a pipeline, create the effective data-model
196
+ */
197
+ declare function constructModelForPipeline(pipeline: DataPipeline): DataModelImpl;
198
+ /** A DataModel that manages middleware data handlers */
199
+ declare class PipelinedDataModel implements DataModelImpl {
200
+ private pipeline;
201
+ private effectiveDataModel;
202
+ readonly hooks: {
203
+ onSet: SyncHook<[BatchSetTransaction], Record<string, any>>;
204
+ };
205
+ constructor(pipeline?: DataPipeline);
206
+ setMiddleware(handlers: DataPipeline): void;
207
+ addMiddleware(handler: DataModelMiddleware): void;
208
+ reset(model?: {}): void;
209
+ set(transaction: BatchSetTransaction, options?: DataModelOptions): Updates;
210
+ get(binding: BindingInstance, options?: DataModelOptions): any;
211
+ }
212
+
213
+ declare type DependencySets = 'core' | 'children';
214
+ /** A class to track usage of read/writes to/from a data model */
215
+ declare class DependencyTracker {
216
+ protected readDeps: Set<BindingInstance>;
217
+ protected writeDeps: Set<BindingInstance>;
218
+ protected namedSet: DependencySets;
219
+ private namedDependencySets;
220
+ constructor();
221
+ protected createSubset(name: DependencySets, force?: boolean): void;
222
+ /** Grab all of the bindings that this depended on */
223
+ getDependencies(name?: DependencySets): Set<BindingInstance>;
224
+ trackSubset(name: DependencySets): void;
225
+ trackDefault(): void;
226
+ /** Grab all of the bindings this wrote to */
227
+ getModified(name?: DependencySets): Set<BindingInstance>;
228
+ /**
229
+ * Check to see if the dataModel has read the value at the given binding
230
+ *
231
+ * @param binding - The binding you want to check for
232
+ */
233
+ readsBinding(binding: BindingInstance): boolean;
234
+ /**
235
+ * Check to see if the dataModel has written to the binding
236
+ */
237
+ writesBinding(binding: BindingInstance): boolean;
238
+ /** Reset all tracking of dependencies */
40
239
  reset(): void;
41
- useSharedState<T>(key: string | symbol): (initialState: T) => readonly [T, (newState: T) => void];
42
- getLocalStateFunction<T>(key: symbol, countKey: symbol): (initialState: T) => readonly [T, (newState: T) => void];
240
+ protected addReadDep(binding: BindingInstance, namedSet?: DependencySets): void;
241
+ protected addWriteDep(binding: BindingInstance, namedSet?: DependencySets): void;
242
+ addChildReadDep(binding: BindingInstance): void;
243
+ }
244
+ /** Middleware that tracks dependencies of read/written data */
245
+ declare class DependencyMiddleware extends DependencyTracker implements DataModelMiddleware {
246
+ constructor();
247
+ set(transaction: BatchSetTransaction, options?: DataModelOptions, next?: DataModelImpl | undefined): Updates;
248
+ get(binding: BindingInstance, options?: DataModelOptions, next?: DataModelImpl | undefined): any;
249
+ }
250
+ /** A data-model that tracks dependencies of read/written data */
251
+ declare class DependencyModel<Options = DataModelOptions> extends DependencyTracker implements DataModelImpl<Options> {
252
+ private readonly rootModel;
253
+ constructor(rootModel: DataModelImpl<Options>);
254
+ set(transaction: BatchSetTransaction, options?: Options): Updates;
255
+ get(binding: BindingInstance, options?: Options): any;
43
256
  }
44
257
 
45
- /** Transform function that is ran on the Asset before it's resolved */
46
- declare type BeforeTransformFunction<AuthoredAsset extends Asset = Asset> = (asset: Node.Asset<AuthoredAsset> | Node.View<AuthoredAsset>, options: Resolve.NodeResolveOptions, store: Store) => Node.Node;
47
- /** Transform function that is ran on the Asset after it's resolved */
48
- declare type TransformFunction<AuthoredAsset extends Asset = Asset, TransformedAsset extends Asset = AuthoredAsset> = (asset: AuthoredAsset, options: Resolve.NodeResolveOptions, store: Store) => TransformedAsset;
49
- interface TransformFunctions {
50
- /** A function that is executed as an AST -> AST transform before resolving the node to a value */
51
- beforeResolve?: BeforeTransformFunction<any>;
52
- /** A function to resolve an AST to a value */
53
- resolve?: TransformFunction<any>;
258
+ /**
259
+ * A model that does nothing
260
+ * Helpful for testing and other default DataModel applications
261
+ */
262
+ declare class NOOPDataModel implements DataModelImpl {
263
+ get(): undefined;
264
+ set(): never[];
265
+ }
266
+ /** You only really need 1 instance of the NOOP model */
267
+ declare const NOOP_MODEL: NOOPDataModel;
268
+
269
+ /**
270
+ * A data model that stores data in an in-memory JS object
271
+ */
272
+ declare class LocalModel implements DataModelImpl {
273
+ model: {
274
+ [key: string]: any;
275
+ };
276
+ constructor(model?: {});
277
+ reset(model?: {}): void;
278
+ get(binding?: BindingInstance): any;
279
+ set(transaction: BatchSetTransaction): Updates;
280
+ }
281
+
282
+ declare type LogFn = (...args: Array<any>) => void;
283
+ declare const severities: readonly ["trace", "debug", "info", "warn", "error"];
284
+ declare type Severity = typeof severities[number];
285
+ declare type Logger = Record<Severity, LogFn>;
286
+ declare type LoggerProvider = () => Logger | undefined;
287
+
288
+ declare type ConsoleHandler = Pick<typeof console, 'log' | 'warn' | 'error'>;
289
+ /** A Logger implementation that uses console */
290
+ declare class ConsoleLogger implements Logger {
291
+ private severity;
292
+ private _console;
293
+ constructor(severity?: Severity, _console?: ConsoleHandler);
294
+ setSeverity(severity: Severity): void;
295
+ private getConsoleFn;
296
+ private createHandler;
297
+ readonly trace: (...args: any[]) => void;
298
+ readonly debug: (...args: any[]) => void;
299
+ readonly info: (...args: any[]) => void;
300
+ readonly warn: (...args: any[]) => void;
301
+ readonly error: (...args: any[]) => void;
302
+ }
303
+
304
+ /** A logger implementation that goes nowhere */
305
+ declare class NoopLogger implements Logger {
306
+ readonly trace: () => void;
307
+ readonly debug: () => void;
308
+ readonly info: () => void;
309
+ readonly warn: () => void;
310
+ readonly error: () => void;
311
+ }
312
+
313
+ /** A logger that has a tapable subscriptions to callbacks */
314
+ declare class TapableLogger implements Logger {
315
+ readonly hooks: {
316
+ trace: SyncHook<[any[]], Record<string, any>>;
317
+ debug: SyncHook<[any[]], Record<string, any>>;
318
+ info: SyncHook<[any[]], Record<string, any>>;
319
+ warn: SyncHook<[any[]], Record<string, any>>;
320
+ error: SyncHook<[any[]], Record<string, any>>;
321
+ log: SyncHook<["error" | "trace" | "debug" | "info" | "warn", any[]], Record<string, any>>;
322
+ };
323
+ private logHandlers;
324
+ private createHandler;
325
+ addHandler(logHandler: Logger): void;
326
+ removeHandler(logHandler: Logger): void;
327
+ readonly trace: (...args: any[]) => void;
328
+ readonly debug: (...args: any[]) => void;
329
+ readonly info: (...args: any[]) => void;
330
+ readonly warn: (...args: any[]) => void;
331
+ readonly error: (...args: any[]) => void;
332
+ }
333
+
334
+ /**
335
+ * The ProxyLogger allows a user to log to another Logger instance that may not exist yet
336
+ */
337
+ declare class ProxyLogger implements Logger {
338
+ private proxiedLoggerProvider;
339
+ constructor(loggerProvider: LoggerProvider);
340
+ private createHandler;
341
+ readonly trace: (...args: any[]) => void;
342
+ readonly debug: (...args: any[]) => void;
343
+ readonly info: (...args: any[]) => void;
344
+ readonly warn: (...args: any[]) => void;
345
+ readonly error: (...args: any[]) => void;
346
+ }
347
+
348
+ declare type ExpressionLiteralType = string | number | boolean | undefined | null;
349
+ declare type ExpressionType = object | ExpressionLiteralType | Array<ExpressionLiteralType> | ExpressionNode;
350
+ interface OperatorProcessingOptions {
351
+ /**
352
+ * When set to a falsy value, the arguments passed to the handler will be raw AST Nodes
353
+ * This enables lazy evaluation of arguments
354
+ */
355
+ resolveParams: boolean;
356
+ }
357
+ declare type BinaryOperatorBasic = (left: any, right: any) => unknown;
358
+ declare type BinaryOperatorAdvanced = OperatorProcessingOptions & ((ctx: ExpressionContext, left: any, right: any) => unknown);
359
+ declare type BinaryOperator = BinaryOperatorAdvanced | BinaryOperatorBasic;
360
+ declare type UnaryOperator = ((arg: any) => unknown) | (((ctx: ExpressionContext, arg: any) => unknown) & OperatorProcessingOptions);
361
+ interface ExpressionContext {
362
+ /** A means of executing an expression */
363
+ evaluate: (expr: ExpressionType) => unknown;
364
+ /** The data model that expression handlers can use when fetching data */
365
+ model: DataModelWithParser;
366
+ /** A logger to use */
367
+ logger?: Logger;
368
+ }
369
+ declare type ExpressionHandler<T extends readonly unknown[] = unknown[], R = void> = ((context: ExpressionContext, ...args: T) => R) & Partial<OperatorProcessingOptions>;
370
+ declare const ExpNodeOpaqueIdentifier: unique symbol;
371
+ /** Checks if the input is an already processed Expression node */
372
+ declare function isExpressionNode(x: any): x is ExpressionNode;
373
+ interface BaseNode<T> {
374
+ /** The thing to discriminate the AST type on */
375
+ type: T;
376
+ /** How to tell this apart from other objects */
377
+ __id: typeof ExpNodeOpaqueIdentifier;
378
+ }
379
+ /** A helper interface for nodes that container left and right children */
380
+ interface DirectionalNode {
381
+ /** The left node. Often for the left hand side of an expression */
382
+ left: ExpressionNode;
383
+ /** The right child. Often for the right hand side of an expression */
384
+ right: ExpressionNode;
385
+ }
386
+ interface LiteralNode extends BaseNode<'Literal'> {
387
+ /** A node that holds a literal value */
388
+ value: string | number;
389
+ /** The unprocessed value */
390
+ raw?: any;
391
+ }
392
+ interface BinaryNode extends BaseNode<'BinaryExpression'>, DirectionalNode {
393
+ /** The operation to perform on the nodes */
394
+ operator: string;
395
+ }
396
+ interface LogicalNode extends BaseNode<'LogicalExpression'> {
397
+ /** The left hand side of the equation */
398
+ left: any;
399
+ /** The right hand side of the equation */
400
+ right: any;
401
+ /** The logical operation to perform on the nodes */
402
+ operator: string;
403
+ }
404
+ interface UnaryNode extends BaseNode<'UnaryExpression'> {
405
+ /** The operation to perform on the node */
406
+ operator: string;
407
+ /** The single argument that the operation should be performed on */
408
+ argument: any;
409
+ }
410
+ declare type ThisNode = BaseNode<'ThisExpression'>;
411
+ interface ModelRefNode extends BaseNode<'ModelRef'> {
412
+ /** The binding that the model reference points to */
413
+ ref: string;
414
+ }
415
+ interface ObjectNode extends BaseNode<'Object'> {
416
+ /** */
417
+ attributes: Array<{
418
+ /** The property name of the object */
419
+ key: any;
420
+ /** the associated value */
421
+ value: any;
422
+ }>;
423
+ }
424
+ interface MemberExpressionNode extends BaseNode<'MemberExpression'> {
425
+ /** The object to be introspected */
426
+ object: ExpressionNode;
427
+ /** If the property uses . or open-bracket */
428
+ computed: boolean;
429
+ /** The property to access on the object */
430
+ property: ExpressionNode;
431
+ }
432
+ interface ConditionalExpressionNode extends BaseNode<'ConditionalExpression'> {
433
+ /** The test for the ternary */
434
+ test: ExpressionNode;
435
+ /** The truthy case for the ternary */
436
+ consequent: ExpressionNode;
437
+ /** The falsy case for the ternary */
438
+ alternate: ExpressionNode;
439
+ }
440
+ interface CompoundNode extends BaseNode<'Compound'> {
441
+ /** The contents of the compound expression */
442
+ body: ExpressionNode[];
443
+ }
444
+ interface CallExpressionNode extends BaseNode<'CallExpression'> {
445
+ /** The arguments to the function */
446
+ args: any[];
447
+ /** The function name */
448
+ callTarget: IdentifierNode;
449
+ }
450
+ interface ArrayExpressionNode extends BaseNode<'ArrayExpression'> {
451
+ /** The items in an array */
452
+ elements: any[];
453
+ }
454
+ interface IdentifierNode extends BaseNode<'Identifier'> {
455
+ /** The variable name */
456
+ name: string;
457
+ }
458
+ declare type AssignmentNode = BaseNode<'Assignment'> & DirectionalNode;
459
+ interface ModificationNode extends BaseNode<'Modification'>, DirectionalNode {
460
+ /** The operator for the modification */
461
+ operator: string;
462
+ }
463
+ declare type ExpressionNode = LiteralNode | BinaryNode | LogicalNode | UnaryNode | ThisNode | ModelRefNode | MemberExpressionNode | ConditionalExpressionNode | CompoundNode | CallExpressionNode | ArrayExpressionNode | IdentifierNode | AssignmentNode | ModificationNode | ObjectNode;
464
+ declare type ExpressionNodeType = ExpressionNode['type'];
465
+
466
+ interface HookOptions extends ExpressionContext {
467
+ /** Given an expression node */
468
+ resolveNode: (node: ExpressionNode) => any;
469
+ }
470
+ declare type ExpressionEvaluatorOptions = Omit<HookOptions, 'resolveNode' | 'evaluate'>;
471
+ declare type ExpressionEvaluatorFunction = (exp: ExpressionType, options?: ExpressionEvaluatorOptions) => any;
472
+ /**
473
+ * The expression evaluator is responsible for parsing and executing anything in the custom expression language
474
+ * */
475
+ declare class ExpressionEvaluator {
476
+ private readonly vars;
477
+ readonly hooks: {
478
+ /** Resolve an AST node for an expression to a value */
479
+ resolve: SyncWaterfallHook<[any, ExpressionNode, HookOptions], Record<string, any>>;
480
+ /**
481
+ * An optional means of handling an error in the expression execution
482
+ * Return true if handled, to stop propagation of the error
483
+ */
484
+ onError: SyncBailHook<[Error], true, Record<string, any>>;
485
+ };
486
+ private readonly expressionsCache;
487
+ private readonly defaultHookOptions;
488
+ readonly operators: {
489
+ binary: Map<string, BinaryOperator>;
490
+ unary: Map<string, UnaryOperator>;
491
+ expressions: Map<string, ExpressionHandler<any, any>>;
492
+ };
493
+ reset(): void;
494
+ constructor(defaultOptions: ExpressionEvaluatorOptions);
495
+ evaluate(expression: ExpressionType, options?: ExpressionEvaluatorOptions): any;
496
+ addExpressionFunction<T extends readonly unknown[], R>(name: string, handler: ExpressionHandler<T, R>): void;
497
+ addBinaryOperator(operator: string, handler: BinaryOperator): void;
498
+ addUnaryOperator(operator: string, handler: UnaryOperator): void;
499
+ setExpressionVariable(name: string, value: unknown): void;
500
+ getExpressionVariable(name: string): unknown;
501
+ private _execAST;
502
+ private _execString;
503
+ private _resolveNode;
504
+ }
505
+
506
+ /** Generates a function by removing the first context argument */
507
+ declare function withoutContext<T extends unknown[], Return>(fn: (...args: T) => Return): ExpressionHandler<T, Return>;
508
+
509
+ declare type FormatOptions = Omit<Formatting.Reference, 'type'>;
510
+ /**
511
+ * The return types for the schema don't include options.
512
+ * These are already sent to the generic formatter function for that type
513
+ */
514
+ declare type FormatFunction<From, To = From, Options = unknown> = (val: From, options?: Options) => To | undefined;
515
+ declare type FormatHandler<From, To = From> = (val: From) => To;
516
+ interface FormatDefinition<DataModelType, UserDisplayType> {
517
+ /**
518
+ * A function to format data (from the data-model to the user).
519
+ * Defaults to the identify function
520
+ */
521
+ format: FormatHandler<DataModelType, UserDisplayType>;
522
+ /**
523
+ * A function to invert the formatting (from the user to the data-model)
524
+ * Defaults to the identify function.
525
+ */
526
+ deformat: FormatHandler<UserDisplayType, DataModelType>;
527
+ }
528
+ interface FormatType<DataModelType, UserDisplayType = DataModelType, Options = undefined> {
529
+ /**
530
+ * The name of the formatter.
531
+ * This corresponds to the 'type' format property when creating a DataType
532
+ */
533
+ name: string;
534
+ /**
535
+ * An optional function to format data for display to the user.
536
+ * This goes from dataModel -> UI display
537
+ */
538
+ format?: FormatFunction<DataModelType | UserDisplayType, UserDisplayType, Options>;
539
+ /**
540
+ * An optional function for undo the action of a format function for storage.
541
+ * This goes from UI -> dataModel
542
+ */
543
+ deformat?: FormatFunction<UserDisplayType | DataModelType, DataModelType, Options>;
544
+ }
545
+
546
+ interface NamedState {
547
+ /** The name of the navigation node */
548
+ name: string;
549
+ /** The nav node */
550
+ value: NavigationFlowState;
551
+ }
552
+ interface TransitionOptions {
553
+ /** Ignore any validations or other signals preventing the transition from taking place */
554
+ force?: boolean;
555
+ }
556
+ declare type TransitionFunction = (name: string, options?: TransitionOptions) => void;
557
+ /** The Content navigation state machine */
558
+ declare class FlowInstance {
559
+ private flow;
560
+ private log?;
561
+ private history;
562
+ private flowPromise?;
563
+ readonly id: string;
564
+ currentState?: NamedState;
565
+ readonly hooks: {
566
+ beforeStart: SyncBailHook<[NavigationFlow], NavigationFlow, Record<string, any>>;
567
+ /** A callback when the onStart node was present */
568
+ onStart: SyncHook<[any], Record<string, any>>;
569
+ /** A callback when the onEnd node was present */
570
+ onEnd: SyncHook<[any], Record<string, any>>;
571
+ /** A hook to intercept and block a transition */
572
+ skipTransition: SyncBailHook<[NamedState | undefined], boolean | undefined, Record<string, any>>;
573
+ /** A chance to manipulate the flow-node used to calculate the given transition used */
574
+ beforeTransition: SyncWaterfallHook<[_player_ui_types.NavigationFlowViewState | _player_ui_types.NavigationFlowFlowState | _player_ui_types.NavigationFlowActionState | _player_ui_types.NavigationFlowExternalState, string], Record<string, any>>;
575
+ /** A chance to manipulate the flow-node calculated after a transition */
576
+ resolveTransitionNode: SyncWaterfallHook<[NavigationFlowState], Record<string, any>>;
577
+ /** A callback when a transition from 1 state to another was made */
578
+ transition: SyncHook<[NamedState | undefined, NamedState], Record<string, any>>;
579
+ };
580
+ constructor(id: string, flow: NavigationFlow, options?: {
581
+ /** Logger instance to use */
582
+ logger?: Logger;
583
+ });
584
+ /** Start the state machine */
585
+ start(): Promise<NavigationFlowEndState>;
586
+ transition(transitionValue: string, options?: TransitionOptions): void;
587
+ private pushHistory;
588
+ }
589
+
590
+ /** A manager for the navigation section of a Content blob */
591
+ declare class FlowController {
592
+ readonly hooks: {
593
+ flow: SyncHook<[FlowInstance], Record<string, any>>;
594
+ };
595
+ private readonly log?;
596
+ private navigation;
597
+ private navStack;
598
+ current?: FlowInstance;
599
+ constructor(navigation: Navigation, options?: {
600
+ /** A logger instance to use */
601
+ logger?: Logger;
602
+ });
603
+ /** Navigate to another state in the state-machine */
604
+ transition(stateTransition: string, options?: TransitionOptions): void;
605
+ private addNewFlow;
606
+ private run;
607
+ start(): Promise<NavigationFlowEndState>;
608
+ }
609
+
610
+ declare type AnyAssetType = Asset<string>;
611
+ declare enum NodeType {
612
+ Asset = "asset",
613
+ View = "view",
614
+ Applicability = "applicability",
615
+ Template = "template",
616
+ Value = "value",
617
+ MultiNode = "multi-node",
618
+ Switch = "switch",
619
+ Unknown = "unknown",
620
+ Empty = "empty"
621
+ }
622
+ declare namespace Node {
623
+ type ChildrenTypes = NodeType.Asset | NodeType.Value | NodeType.View;
624
+ interface Base<T extends NodeType> {
625
+ /** Every node contains a type to distinguish it from other nodes */
626
+ type: T;
627
+ /** Every node (outside of the root) contains a reference to it's parent */
628
+ parent?: Node;
629
+ }
630
+ type PathSegment = string | number;
631
+ interface Child {
632
+ /** The path of the child relative to the parent */
633
+ path: PathSegment[];
634
+ /** If true, the path points to an array, and the value will be appended to it result */
635
+ array?: boolean;
636
+ /** The child node */
637
+ value: Node;
638
+ }
639
+ interface BaseWithChildren<T extends NodeType> extends Base<T> {
640
+ /** Any node that contains a list of children underneath it */
641
+ children?: Child[];
642
+ }
643
+ interface Asset<T extends AnyAssetType = AnyAssetType> extends BaseWithChildren<NodeType.Asset>, PluginOptions {
644
+ /** Any asset nested within a view */
645
+ value: T;
646
+ }
647
+ interface View<T extends AnyAssetType = AnyAssetType> extends BaseWithChildren<NodeType.View>, PluginOptions {
648
+ /** The root of the parsed view */
649
+ value: T;
650
+ }
651
+ interface Applicability extends Base<NodeType.Applicability> {
652
+ /** The expression to execute that determines applicability of the target node */
653
+ expression: Expression;
654
+ /** The node to use if the expression is truthy */
655
+ value: Node;
656
+ }
657
+ interface Template extends Base<NodeType.Template> {
658
+ /** The location of an array in the model */
659
+ data: Binding;
660
+ /** The template to use when mapping over the data */
661
+ template: unknown;
662
+ /** The number of nested templates so far */
663
+ depth: number;
664
+ /** should the template recomputed when data changes */
665
+ dynamic?: boolean;
666
+ }
667
+ interface Value extends BaseWithChildren<NodeType.Value>, PluginOptions {
668
+ /** A simple node representing a value */
669
+ value: any;
670
+ }
671
+ interface MultiNode extends Base<NodeType.MultiNode> {
672
+ /**
673
+ * Should this list override the target node if they overlap?
674
+ * If not amend the existing list
675
+ */
676
+ override?: boolean;
677
+ /** A list of values that comprise this node */
678
+ values: Array<Node>;
679
+ }
680
+ interface Switch extends Base<NodeType.Switch> {
681
+ /** Should this list be re-computed when data changes */
682
+ dynamic?: boolean;
683
+ /** A list of cases to evaluate in order */
684
+ cases: SwitchCase[];
685
+ }
686
+ interface SwitchCase {
687
+ /** The expression to evaluate for a single case statement */
688
+ case: Expression | true;
689
+ /** The value to use if this case is true */
690
+ value: Value;
691
+ }
692
+ interface PluginOptions {
693
+ /** A list of plugins */
694
+ plugins?: {
695
+ /** StringResolverPlugin options */
696
+ stringResolver?: {
697
+ /**
698
+ * An optional array of node properties to skip during string resolution
699
+ * Specified in the AssetTransformPlugin
700
+ */
701
+ propertiesToSkip?: string[];
702
+ };
703
+ };
704
+ }
705
+ type Unknown = Base<NodeType.Unknown>;
706
+ type Empty = Base<NodeType.Empty>;
707
+ type ViewOrAsset = View | Asset;
708
+ type Node = Asset | Applicability | Template | Value | View | MultiNode | Switch | Unknown | Empty;
709
+ }
710
+
711
+ declare const EMPTY_NODE: Node.Empty;
712
+ interface ParseObjectOptions {
713
+ /** how nested the templated is */
714
+ templateDepth?: number;
715
+ }
716
+ /**
717
+ * The Parser is the way to take an incoming view from the user and parse it into an AST.
718
+ * It provides a few ways to interact with the parsing, including mutating an object before and after creation of an AST node
719
+ */
720
+ declare class Parser {
721
+ readonly hooks: {
722
+ /**
723
+ * A hook to interact with an object _before_ parsing it into an AST
724
+ *
725
+ * @param value - The object we're are about to parse
726
+ * @returns - A new value to parse.
727
+ * If undefined, the original value is used.
728
+ * If null, we stop parsing this node.
729
+ */
730
+ onParseObject: SyncWaterfallHook<[object, NodeType], Record<string, any>>;
731
+ /**
732
+ * A callback to interact with an AST _after_ we parse it into the AST
733
+ *
734
+ * @param value - The object we parsed
735
+ * @param node - The AST node we generated
736
+ * @returns - A new AST node to use
737
+ * If undefined, the original value is used.
738
+ * If null, we ignore this node all together
739
+ */
740
+ onCreateASTNode: SyncWaterfallHook<[Node.Node | null | undefined, object], Record<string, any>>;
741
+ determineNodeType: SyncBailHook<[string | object], NodeType, Record<string, any>>;
742
+ parseNode: SyncBailHook<[obj: object, nodeType: Node.ChildrenTypes, parseOptions: ParseObjectOptions, determinedNodeType: NodeType | null], Node.Node, Record<string, any>>;
743
+ };
744
+ parseView(value: AnyAssetType): Node.View;
745
+ createASTNode(node: Node.Node | null, value: any): Node.Node | null;
746
+ parseObject(obj: object, type?: Node.ChildrenTypes, options?: ParseObjectOptions): Node.Node | null;
747
+ }
748
+
749
+ declare namespace Resolve {
750
+ interface Validation {
751
+ /** Fetch the data-type for the given binding */
752
+ type(binding: BindingLike): Schema.DataType | undefined;
753
+ /** Get all currently applicable validation errors */
754
+ getAll(): Map<BindingInstance, ValidationResponse> | undefined;
755
+ /** Internal Method to lookup if there is a validation for the given binding */
756
+ _getValidationForBinding(binding: BindingLike): ValidationResponse | undefined;
757
+ /** Get field level error for the specific binding */
758
+ get(binding: BindingLike, options?: {
759
+ /** If this binding should also be tracked for validations */
760
+ track: boolean;
761
+ }): ValidationResponse | undefined;
762
+ /** Get errors for all children regardless of section */
763
+ getChildren(type: Validation.DisplayTarget): Array<ValidationResponse>;
764
+ /** Get errors for all children solely in this section */
765
+ getValidationsForSection(): Array<ValidationResponse>;
766
+ /** Track errors for this binding, and notify the node of changes */
767
+ track: (binding: BindingLike) => void;
768
+ /** Register node as a section */
769
+ register: (options?: {
770
+ /** While type of Display Target group it should register as */
771
+ type: Exclude<Validation.DisplayTarget, 'field'>;
772
+ }) => void;
773
+ }
774
+ interface BaseOptions {
775
+ /** A logger to use */
776
+ logger?: Logger;
777
+ /** An optional set of validation features */
778
+ validation?: Validation;
779
+ /** Parse a raw valy into an AST node */
780
+ parseNode?: (node: any) => Node.Node | null;
781
+ /** A function to move the state to a new place */
782
+ transition?: TransitionFunction;
783
+ /** The hub for data invariants and metaData associated with the data model */
784
+ schema: SchemaController;
785
+ }
786
+ interface NodeDataOptions {
787
+ /** The data to set or get data from */
788
+ model: DataModelWithParser<DataModelOptions>;
789
+ /**
790
+ * A function to format a given a value (given a binding) for display to the user
791
+ * Note: this doesn't persist any changes in the model.
792
+ */
793
+ format: (binding: BindingLike, value: any) => any;
794
+ /**
795
+ * A function to format a given value using a formatting reference.
796
+ * The default behavior is the identity function.
797
+ */
798
+ formatValue: (formatReference: Formatting.Reference, value: any) => any;
799
+ }
800
+ type NodeResolveOptions = BaseOptions & {
801
+ /** Execute the expression and return it's result */
802
+ evaluate: (exp: ExpressionType) => any;
803
+ /** All parameters for how to process data */
804
+ data: NodeDataOptions;
805
+ /** The data dependencies that were requested during the resolution */
806
+ getDependencies?(scope?: 'core' | 'children'): Set<BindingInstance>;
807
+ /** original node */
808
+ node?: Node.Node;
809
+ };
810
+ type ResolverOptions = BaseOptions & {
811
+ /** The data model to set or get data from */
812
+ model: DataModelImpl<DataModelOptions>;
813
+ /** A formatter function to call */
814
+ format?: (binding: BindingInstance, value: any) => any;
815
+ /**
816
+ * A function to format a given value using a formatting reference.
817
+ * The default behavior is the identity function.
818
+ */
819
+ formatValue?: (formatReference: Formatting.Reference, value: any) => any;
820
+ /** An evaluator to execute an expression */
821
+ evaluator: ExpressionEvaluator;
822
+ /** A fn to parse a raw binding into a binding object */
823
+ parseBinding: BindingFactory;
824
+ };
825
+ interface ResolvedNode {
826
+ /** The original node */
827
+ node: Node.Node;
828
+ /** The data dependencies that were requested during the resolution */
829
+ dependencies: Set<BindingInstance>;
830
+ /** The final value */
831
+ value: any;
832
+ }
833
+ type NodeTransformFunction = (node: Node.Node, options: NodeResolveOptions) => Node.Node | null;
834
+ type NodeResolveFunction = (value: any, node: Node.Node, options: NodeResolveOptions) => any;
835
+ interface Plugin {
836
+ /** A transform function to migrate an AST to another AST */
837
+ beforeResolve?: NodeTransformFunction;
838
+ /** A function to transform an AST to a resolved value */
839
+ resolve?: NodeResolveFunction;
840
+ /** A function to process a resolved value before completing the node */
841
+ afterResolve?: NodeResolveFunction;
842
+ }
843
+ }
844
+
845
+ /** Check to see if and of the data-changes affect the given dependencies */
846
+ declare function caresAboutDataChanges(dataChanges?: Set<BindingInstance>, dependencies?: Set<BindingInstance>): boolean;
847
+ /** Convert the options object for a resolver to one for a node */
848
+ declare function toNodeResolveOptions(resolverOptions: Resolve.ResolverOptions): Resolve.NodeResolveOptions;
849
+
850
+ interface NodeUpdate extends Resolve.ResolvedNode {
851
+ /** A flag to track if a node has changed since the last resolution */
852
+ updated: boolean;
853
+ }
854
+ /**
855
+ * The Resolver is the way to take a parsed AST graph of a view and resolve it to a concrete representation of the current user state
856
+ * It combines the ability to mutate ast nodes before resolving, as well as the mutating the resolved objects while parsing
857
+ */
858
+ declare class Resolver {
859
+ readonly hooks: {
860
+ /** A hook to allow skipping of the resolution tree for a specific node */
861
+ skipResolve: SyncWaterfallHook<[boolean, Node.Node, Resolve.NodeResolveOptions], Record<string, any>>;
862
+ /** An event emitted before calculating the next update */
863
+ beforeUpdate: SyncHook<[Set<BindingInstance> | undefined], Record<string, any>>;
864
+ /** An event emitted after calculating the next update */
865
+ afterUpdate: SyncHook<[any], Record<string, any>>;
866
+ /** The options passed to a node to resolve it to an object */
867
+ resolveOptions: SyncWaterfallHook<[Resolve.NodeResolveOptions, Node.Node], Record<string, any>>;
868
+ /** A hook to transform the AST node into a new AST node before resolving it */
869
+ beforeResolve: SyncWaterfallHook<[Node.Node | null, Resolve.NodeResolveOptions], Record<string, any>>;
870
+ /**
871
+ * A hook to transform an AST node into it's resolved value.
872
+ * This runs _before_ any children are resolved
873
+ */
874
+ resolve: SyncWaterfallHook<[any, Node.Node, Resolve.NodeResolveOptions], Record<string, any>>;
875
+ /**
876
+ * A hook to transform the resolved value of an AST node.
877
+ * This runs _after_ all children nodes are resolved
878
+ */
879
+ afterResolve: SyncWaterfallHook<[any, Node.Node, Resolve.NodeResolveOptions], Record<string, any>>;
880
+ /** Called at the very end of a node's tree being updated */
881
+ afterNodeUpdate: SyncHook<[Node.Node, Node.Node | undefined, NodeUpdate], Record<string, any>>;
882
+ };
883
+ /**
884
+ * The AST tree after beforeResolve is ran mapped to the AST before beforeResolve is ran
885
+ */
886
+ private readonly ASTMap;
887
+ /**
888
+ * The root node in the AST tree we want to resolve
889
+ */
890
+ readonly root: Node.Node;
891
+ /**
892
+ * The cache of the last resolved values when walking the tree.
893
+ * This gets recycled every update to avoid stale data if a node is unused in an update
894
+ */
895
+ private resolveCache;
896
+ /**
897
+ * Cache of node IDs that have been processed to track if nodes have duplicate IDs
898
+ */
899
+ private idCache;
900
+ /**
901
+ * The parameters required to resolve AST nodes
902
+ */
903
+ private readonly options;
904
+ /**
905
+ * Tapable logger for logging errors encountered during view resolution
906
+ */
907
+ private logger?;
908
+ constructor(root: Node.Node, options: Resolve.ResolverOptions);
909
+ getSourceNode(convertedAST: Node.Node): Node.Node | undefined;
910
+ update(changes?: Set<BindingInstance>): any;
911
+ private getNodeID;
912
+ private getPreviousResult;
913
+ private computeTree;
914
+ }
915
+
916
+ /** The basic view api */
917
+ interface View {
918
+ /** The hooks for a view */
919
+ hooks: {
920
+ /** A hook when a parser is created for this view */
921
+ parser: SyncHook<[Parser]>;
922
+ /** A hook when a resolver is created for this view */
923
+ resolver: SyncHook<[Resolver]>;
924
+ };
925
+ }
926
+ /** A plugin for a view */
927
+ interface ViewPlugin {
928
+ /** Called with a view instance */
929
+ apply(view: View): void;
930
+ }
931
+
932
+ /** Config options that are required to resolve/update a view */
933
+ declare type Options$2 = Resolve.NodeResolveOptions;
934
+
935
+ interface TemplateItemInfo {
936
+ /** The index of the data for the current iteration of the template */
937
+ index: number;
938
+ /** The data for the current iteration of the template */
939
+ data: any;
940
+ /** The depth of the template node */
941
+ depth: number;
942
+ }
943
+ interface TemplateSubstitution {
944
+ /** Regular expression to find and replace. The global flag will be always be added to this expression. */
945
+ expression: string | RegExp;
946
+ /** The value to replace matches with. */
947
+ value: string;
948
+ }
949
+ /** A view plugin to resolve/manage templates */
950
+ declare class TemplatePlugin implements ViewPlugin {
951
+ private readonly options;
952
+ hooks: {
953
+ resolveTemplateSubstitutions: SyncWaterfallHook<[TemplateSubstitution[], TemplateItemInfo], Record<string, any>>;
954
+ };
955
+ constructor(options: Options$2);
956
+ private parseTemplate;
957
+ applyParser(parser: Parser): void;
958
+ applyResolverHooks(resolver: Resolver): void;
959
+ apply(view: View): void;
960
+ }
961
+
962
+ /** A plugin that resolves all string references for each node */
963
+ declare class StringResolverPlugin implements ViewPlugin {
964
+ applyResolver(resolver: Resolver): void;
965
+ apply(view: View): void;
966
+ }
967
+
968
+ /** A view plugin to remove inapplicable assets from the tree */
969
+ declare class ApplicabilityPlugin implements ViewPlugin {
970
+ applyResolver(resolver: Resolver): void;
971
+ applyParser(parser: Parser): void;
972
+ apply(view: View): void;
973
+ }
974
+
975
+ /** A view plugin to resolve switches */
976
+ declare class SwitchPlugin implements ViewPlugin {
977
+ private readonly options;
978
+ constructor(options: Options$2);
979
+ private resolveSwitch;
980
+ applyParser(parser: Parser): void;
981
+ applyResolver(resolver: Resolver): void;
982
+ apply(view: View): void;
983
+ }
984
+
985
+ /** A stateful view instance from an content */
986
+ declare class ViewInstance implements ValidationProvider {
987
+ hooks: {
988
+ onUpdate: SyncHook<[_player_ui_types.Asset<string> & {
989
+ validation?: _player_ui_types.Validation.CrossfieldReference[] | undefined;
990
+ }], Record<string, any>>;
991
+ parser: SyncHook<[Parser], Record<string, any>>;
992
+ resolver: SyncHook<[Resolver], Record<string, any>>;
993
+ templatePlugin: SyncHook<[TemplatePlugin], Record<string, any>>;
994
+ };
995
+ private resolver?;
996
+ readonly initialView: View$1;
997
+ readonly resolverOptions: Resolve.ResolverOptions;
998
+ private rootNode?;
999
+ private validationProvider?;
1000
+ private templatePlugin;
1001
+ lastUpdate: Record<string, any> | undefined;
1002
+ constructor(initialView: View$1, resolverOptions: Resolve.ResolverOptions);
1003
+ update(changes?: Set<BindingInstance>): any;
1004
+ getValidationsForBinding(binding: BindingInstance): ValidationObject[] | undefined;
1005
+ }
1006
+
1007
+ /**
1008
+ * Functions for building AST nodes (relatively) easily
1009
+ */
1010
+ declare class Builder {
1011
+ /**
1012
+ * Creates an asset node
1013
+ *
1014
+ * @param value - the value to put in the asset node
1015
+ */
1016
+ static asset<T extends AnyAssetType>(value: T): Node.Asset<T>;
1017
+ /**
1018
+ * Creates a value node
1019
+ *
1020
+ * @param v - The object to put in the value node
1021
+ */
1022
+ static value(v?: object): Node.Value;
1023
+ /**
1024
+ * Creates a multiNode and associates the multiNode as the parent
1025
+ * of all the value nodes
1026
+ *
1027
+ * @param values - the value or applicability nodes to put in the multinode
1028
+ */
1029
+ static multiNode(...values: (Node.Value | Node.Applicability)[]): Node.MultiNode;
1030
+ /**
1031
+ * Adds a child node to a node
1032
+ *
1033
+ * @param node - The node to add a child to
1034
+ * @param path - The path at which to add the child
1035
+ * @param child - The child node
1036
+ */
1037
+ static addChild<N extends Node.BaseWithChildren<NT>, NT extends NodeType>(node: N, path: Node.PathSegment | Node.PathSegment[], child: Node.Node): N;
54
1038
  }
55
- declare type TransformRegistry = Registry<TransformFunctions>;
56
1039
 
57
1040
  interface BindingTracker {
58
1041
  /** Get the bindings currently being tracked for validation */
59
1042
  getBindings(): Set<BindingInstance>;
60
1043
  }
61
- interface Options {
1044
+ interface Options$1 {
62
1045
  /** Parse a binding from a view */
63
1046
  parseBinding: BindingFactory;
64
1047
  /** Callbacks when events happen */
@@ -71,7 +1054,7 @@ interface Options {
71
1054
  declare class ValidationBindingTrackerViewPlugin implements ViewPlugin, BindingTracker {
72
1055
  private options;
73
1056
  private trackedBindings;
74
- constructor(options: Options);
1057
+ constructor(options: Options$1);
75
1058
  /** Fetch the tracked bindings in the current view */
76
1059
  getBindings(): Set<BindingInstance>;
77
1060
  /** Attach hooks to the given resolver */
@@ -176,7 +1159,7 @@ declare class ValidationController implements BindingTracker {
176
1159
  private updateValidationsForView;
177
1160
  private setCompare;
178
1161
  private get activeBindings();
179
- getValidator(type: string): _player_ui_validator.ValidatorFunction<unknown> | undefined;
1162
+ getValidator(type: string): ValidatorFunction<unknown> | undefined;
180
1163
  getBindings(): Set<BindingInstance>;
181
1164
  /** Executes all known validations for the tracked bindings using the given model */
182
1165
  validateView(trigger?: Validation.Trigger): {
@@ -189,6 +1172,37 @@ declare class ValidationController implements BindingTracker {
189
1172
  forView(parser: BindingFactory): Resolve.Validation;
190
1173
  }
191
1174
 
1175
+ interface Store {
1176
+ useLocalState<T>(initialState: T): readonly [T, (value: T) => void];
1177
+ useSharedState<T>(key: string | symbol): (initialState: T) => readonly [T, (value: T) => void];
1178
+ }
1179
+ interface SharedStore {
1180
+ getLocalStateFunction<T>(key: string | symbol, countKey: symbol): (initialState: T) => readonly [T, (value: T) => void];
1181
+ useSharedState<T>(key: string | symbol): (initialState: T) => readonly [T, (value: T) => void];
1182
+ }
1183
+ /** A store that holds on to state for a transform */
1184
+ declare class LocalStateStore implements SharedStore {
1185
+ private state;
1186
+ private updateCallback?;
1187
+ constructor(onUpdate?: () => void);
1188
+ removeKey(key: symbol | string): void;
1189
+ reset(): void;
1190
+ useSharedState<T>(key: string | symbol): (initialState: T) => readonly [T, (newState: T) => void];
1191
+ getLocalStateFunction<T>(key: symbol, countKey: symbol): (initialState: T) => readonly [T, (newState: T) => void];
1192
+ }
1193
+
1194
+ /** Transform function that is ran on the Asset before it's resolved */
1195
+ declare type BeforeTransformFunction<AuthoredAsset extends Asset = Asset> = (asset: Node.Asset<AuthoredAsset> | Node.View<AuthoredAsset>, options: Resolve.NodeResolveOptions, store: Store) => Node.Node;
1196
+ /** Transform function that is ran on the Asset after it's resolved */
1197
+ declare type TransformFunction<AuthoredAsset extends Asset = Asset, TransformedAsset extends Asset = AuthoredAsset> = (asset: AuthoredAsset, options: Resolve.NodeResolveOptions, store: Store) => TransformedAsset;
1198
+ interface TransformFunctions {
1199
+ /** A function that is executed as an AST -> AST transform before resolving the node to a value */
1200
+ beforeResolve?: BeforeTransformFunction<any>;
1201
+ /** A function to resolve an AST to a value */
1202
+ resolve?: TransformFunction<any>;
1203
+ }
1204
+ declare type TransformRegistry = Registry<TransformFunctions>;
1205
+
192
1206
  /** The status for a flow's execution state */
193
1207
  declare type PlayerFlowStatus = 'not-started' | 'in-progress' | 'completed' | 'error';
194
1208
  /** Common interface for the state of Player's flow execution */
@@ -314,7 +1328,7 @@ declare class ViewController {
314
1328
  currentView?: ViewInstance;
315
1329
  transformRegistry: TransformRegistry;
316
1330
  optimizeUpdates: boolean;
317
- constructor(initialViews: View[], options: Resolve.ResolverOptions & ViewControllerOptions);
1331
+ constructor(initialViews: View$1[], options: Resolve.ResolverOptions & ViewControllerOptions);
318
1332
  private queueUpdate;
319
1333
  private getViewForRef;
320
1334
  onView(state: NavigationFlowViewState): void;
@@ -335,6 +1349,169 @@ declare class AssetTransformCorePlugin {
335
1349
  apply(viewController: ViewController): void;
336
1350
  }
337
1351
 
1352
+ interface ConstantsProvider {
1353
+ /**
1354
+ * Function to add constants to the providers store
1355
+ * - @param data values to add to the constants store
1356
+ */
1357
+ addConstants(data: Record<string, any>, namespace: string): void;
1358
+ /**
1359
+ * Function to retreive constants from the providers store
1360
+ * - @param key Key used for the store access
1361
+ * - @param namespace namespace values were loaded under (defined in the plugin)
1362
+ * - @param fallback Optional - if key doesn't exist in namespace what to return (will return unknown if not provided)
1363
+ */
1364
+ getConstants(key: any, namespace: string, fallback?: any): any;
1365
+ /**
1366
+ * Function to set values to temporarily override certain keys in the perminant store
1367
+ * - @param data values to override store with
1368
+ * - @param namespace namespace to override
1369
+ */
1370
+ setTemporaryValues(data: any, namespace: string): void;
1371
+ /**
1372
+ * Clears any temporary values that were previously set
1373
+ */
1374
+ clearTemporaryValues(): void;
1375
+ }
1376
+ /**
1377
+ * Key/Value store for constants and context for Player
1378
+ */
1379
+ declare class ConstantsController implements ConstantsProvider {
1380
+ /**
1381
+ * Data store is basically a map of namespaces to DataModels to provide some data isolation
1382
+ */
1383
+ private store;
1384
+ /**
1385
+ * Separate store for temporary flow specific overrides.
1386
+ * They are kept in a separate data model to make clearing it easier between flows
1387
+ * and so there is no confusion on what is static and what is temporary
1388
+ */
1389
+ private tempStore;
1390
+ constructor();
1391
+ addConstants(data: any, namespace: string): void;
1392
+ getConstants(key: string, namespace: string, fallback?: any): any;
1393
+ setTemporaryValues(data: any, namespace: string): void;
1394
+ clearTemporaryValues(): void;
1395
+ }
1396
+
1397
+ interface BaseValidationResponse<T = Validation.Severity> {
1398
+ /** The validation message to show to the user */
1399
+ message: string;
1400
+ /** List of parameters associated with a validation. These can be replaced into a templatized message string. */
1401
+ parameters?: Record<string, any>;
1402
+ /** How serious is this violation */
1403
+ severity: T;
1404
+ /** Where this validation should be displayed */
1405
+ displayTarget?: Validation.DisplayTarget;
1406
+ /** The blocking state of this validation */
1407
+ blocking?: boolean | 'once';
1408
+ }
1409
+ interface WarningValidationResponse extends BaseValidationResponse<'warning'> {
1410
+ /** Warning validations can be dismissed without correcting the error */
1411
+ dismiss?: () => void;
1412
+ }
1413
+ declare type ErrorValidationResponse = BaseValidationResponse<'error'>;
1414
+ declare type ValidationResponse = ErrorValidationResponse | WarningValidationResponse;
1415
+ declare type RequiredValidationKeys = 'severity' | 'trigger';
1416
+ declare type ValidationObject = Validation.Reference & Required<Pick<Validation.Reference, RequiredValidationKeys>>;
1417
+ interface ValidationProvider {
1418
+ getValidationsForBinding?(binding: BindingInstance): Array<ValidationObject> | undefined;
1419
+ getValidationsForView?(): Array<ValidationObject> | undefined;
1420
+ }
1421
+ interface ValidatorContext {
1422
+ /** The data to set or get data from */
1423
+ model: DataModelWithParser;
1424
+ /** A means of parsing a binding */
1425
+ parseBinding: BindingFactory;
1426
+ /** Execute the expression and return it's result */
1427
+ evaluate: ExpressionEvaluatorFunction;
1428
+ /** Logger instance to use */
1429
+ logger: Logger;
1430
+ /** The validation object that triggered this function */
1431
+ validation: ValidationObject;
1432
+ /** The constants for messages */
1433
+ constants: ConstantsProvider;
1434
+ }
1435
+ declare type ValidatorFunction<Options = unknown> = (context: ValidatorContext, value: any, options?: Options) => Omit<BaseValidationResponse, 'severity'> | undefined;
1436
+
1437
+ /**
1438
+ * Returns a validation object if the data is invalid or an set of BindingsInstances if the binding itself is a weak ref of another invalid validation
1439
+ */
1440
+ declare type MiddlewareChecker = (binding: BindingInstance, model: DataModelImpl) => ValidationResponse | Set<BindingInstance> | undefined;
1441
+ /**
1442
+ * Middleware for the data-model that caches the results of invalid data
1443
+ */
1444
+ declare class ValidationMiddleware implements DataModelMiddleware {
1445
+ validator: MiddlewareChecker;
1446
+ shadowModelPaths: Map<BindingInstance, any>;
1447
+ private logger?;
1448
+ constructor(validator: MiddlewareChecker, options?: {
1449
+ /** A logger instance */
1450
+ logger?: Logger;
1451
+ });
1452
+ set(transaction: BatchSetTransaction, options?: DataModelOptions, next?: DataModelImpl): Updates;
1453
+ get(binding: BindingInstance, options?: DataModelOptions, next?: DataModelImpl): any;
1454
+ }
1455
+
1456
+ /** A registry that tracks validators */
1457
+ declare class ValidatorRegistry {
1458
+ private registry;
1459
+ constructor();
1460
+ /** Use the given validator name to fetch the handler */
1461
+ get(name: string): ValidatorFunction | undefined;
1462
+ /** Register a new validator */
1463
+ register<T>(name: string, handler: ValidatorFunction<T>): void;
1464
+ }
1465
+
1466
+ /** Expand the authored schema into a set of paths -> DataTypes */
1467
+ declare function parse(schema: Schema.Schema): Map<string, Schema.DataType>;
1468
+ /**
1469
+ * The Schema is the central hub for all data invariants, and metaData associated with the data-model itself
1470
+ * Outside of the types defined in the JSON payload, it doesn't manage or keep any state.
1471
+ * It simply servers as an orchestrator for other modules to interface w/ the schema.
1472
+ */
1473
+ declare class SchemaController implements ValidationProvider {
1474
+ private formatters;
1475
+ private types;
1476
+ readonly schema: Map<string, Schema.DataType>;
1477
+ private bindingSchemaNormalizedCache;
1478
+ readonly hooks: {
1479
+ resolveTypeForBinding: SyncWaterfallHook<[Schema.DataType<unknown> | undefined, BindingInstance], Record<string, any>>;
1480
+ };
1481
+ constructor(schema?: Schema.Schema);
1482
+ addFormatters(fns: Array<FormatType<any, any, FormatOptions>>): void;
1483
+ addDataTypes(types: Array<Schema.DataType<any>>): void;
1484
+ getValidationsForBinding(binding: BindingInstance): Array<ValidationObject> | undefined;
1485
+ private normalizeBinding;
1486
+ getType(binding: BindingInstance): Schema.DataType | undefined;
1487
+ getApparentType(binding: BindingInstance): Schema.DataType | undefined;
1488
+ getTypeDefinition(dataType: string): Schema.DataType<any> | undefined;
1489
+ getFormatterForType(formatReference: Formatting.Reference): FormatDefinition<unknown, unknown> | undefined;
1490
+ /**
1491
+ * Given a binding, fetch a function that's responsible for formatting, and/or de-formatting the data
1492
+ * If no formatter is registered, it will return undefined
1493
+ */
1494
+ getFormatter(binding: BindingInstance): FormatDefinition<unknown, unknown> | undefined;
1495
+ }
1496
+
1497
+ interface Options {
1498
+ /** The model to use when resolving refs */
1499
+ model: DataModelWithParser;
1500
+ /** A function to evaluate an expression */
1501
+ evaluate: (exp: Expression) => any;
1502
+ }
1503
+ /** Search the given string for the coordinates of the next expression to resolve */
1504
+ declare function findNextExp(str: string): {
1505
+ start: number;
1506
+ end: number;
1507
+ } | undefined;
1508
+ /** Finds any subset of the string wrapped in @[]@ and evaluates it as an expression */
1509
+ declare function resolveExpressionsInString(val: string, { evaluate }: Options): string;
1510
+ /** Return a string with all data model references resolved */
1511
+ declare function resolveDataRefsInString(val: string, options: Options): string;
1512
+ /** Recursively resolve all model refs in whatever you pass in */
1513
+ declare function resolveDataRefs<T>(val: T, options: Options): T;
1514
+
338
1515
  interface PlayerPlugin {
339
1516
  /**
340
1517
  * Unique identifier of the plugin.
@@ -434,4 +1611,4 @@ declare class FlowExpPlugin implements PlayerPlugin {
434
1611
  apply(player: Player): void;
435
1612
  }
436
1613
 
437
- export { AssetTransformCorePlugin, BaseFlowState, BeforeTransformFunction, BindingTracker, CompletedState, ControllerState, DataController, ErrorState, FlowExpPlugin, InProgressState, LocalStateStore, NOT_STARTED_STATE, NotStartedState, Player, PlayerConfigOptions, PlayerFlowExecutionData, PlayerFlowState, PlayerFlowStatus, PlayerInfo, PlayerPlugin, RawSetTransaction, RawSetType, StatefulValidationObject, Store, TransformFunction, TransformFunctions, TransformRegistry, ValidationBindingTrackerViewPlugin, ValidationController, ViewController, ViewControllerOptions };
1614
+ export { AnyAssetType, ApplicabilityPlugin, ArrayExpressionNode, AssetTransformCorePlugin, AssignmentNode, BaseFlowState, BaseNode, BatchSetTransaction, BeforeTransformFunction, BinaryNode, BinaryOperator, BinaryOperatorAdvanced, BinaryOperatorBasic, BindingFactory, BindingInstance, BindingLike, BindingParser, BindingParserOptions, BindingTracker, Builder, CallExpressionNode, CompletedState, CompoundNode, ConditionalExpressionNode, ConsoleLogger, ConstantsController, ConstantsProvider, ControllerState, DataController, DataModelImpl, DataModelMiddleware, DataModelOptions, DataModelWithParser, DataPipeline, DependencyMiddleware, DependencyModel, DependencySets, DependencyTracker, DirectionalNode, EMPTY_NODE, ErrorState, ErrorValidationResponse, ExpNodeOpaqueIdentifier, ExpressionContext, ExpressionEvaluator, ExpressionEvaluatorFunction, ExpressionEvaluatorOptions, ExpressionHandler, ExpressionLiteralType, ExpressionNode, ExpressionNodeType, ExpressionType, FlowController, FlowExpPlugin, FlowInstance, FormatDefinition, FormatFunction, FormatHandler, FormatOptions, FormatType, Getter, HookOptions, IdentifierNode, InProgressState, LiteralNode, LocalModel, LocalStateStore, LogFn, Logger, LoggerProvider, LogicalNode, MemberExpressionNode, MiddlewareChecker, ModelRefNode, ModificationNode, NOOPDataModel, NOOP_MODEL, NOT_STARTED_STATE, NamedState, Node, NodeType, NoopLogger, NotStartedState, ObjectNode, OperatorProcessingOptions, Options, ParseObjectOptions, Parser, PipelinedDataModel, Player, PlayerConfigOptions, PlayerFlowExecutionData, PlayerFlowState, PlayerFlowStatus, PlayerInfo, PlayerPlugin, ProxyLogger, ROOT_BINDING, RawBinding, RawBindingSegment, RawSetTransaction, RawSetType, Resolve, Resolver, SIMPLE_BINDING_REGEX, SchemaController, Severity, StatefulValidationObject, Store, StringResolverPlugin, SwitchPlugin, TapableLogger, TemplatePlugin, ThisNode, TransformFunction, TransformFunctions, TransformRegistry, TransitionFunction, TransitionOptions, UnaryNode, UnaryOperator, Updates, ValidationBindingTrackerViewPlugin, ValidationController, ValidationMiddleware, ValidationObject, ValidationProvider, ValidationResponse, ValidatorContext, ValidatorFunction, ValidatorRegistry, ViewController, ViewControllerOptions, ViewInstance, ViewPlugin, WarningValidationResponse, caresAboutDataChanges, constructModelForPipeline, findInArray, findNextExp, getBindingSegments, isBinding, isExpressionNode, maybeConvertToNum, parse, resolveDataRefs, resolveDataRefsInString, resolveExpressionsInString, severities, toModel, toNodeResolveOptions, withParser, withoutContext };