@player-ui/player 0.8.0--canary.307.9621 → 0.8.0-next.0
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.
- package/dist/Player.native.js +11630 -0
- package/dist/Player.native.js.map +1 -0
- package/dist/cjs/index.cjs +5626 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/{index.esm.js → index.legacy-esm.js} +2044 -1667
- package/dist/{index.cjs.js → index.mjs} +2052 -1761
- package/dist/index.mjs.map +1 -0
- package/package.json +29 -63
- package/src/__tests__/data.test.ts +498 -0
- package/src/__tests__/flow.test.ts +312 -0
- package/src/__tests__/helpers/action-exp.plugin.ts +22 -0
- package/src/__tests__/helpers/actions.flow.ts +67 -0
- package/src/__tests__/helpers/binding.plugin.ts +125 -0
- package/src/__tests__/helpers/expression.plugin.ts +88 -0
- package/src/__tests__/helpers/transform-plugin.ts +19 -0
- package/src/__tests__/helpers/validation.flow.ts +56 -0
- package/src/__tests__/player.test.ts +597 -0
- package/src/__tests__/string-resolver.test.ts +186 -0
- package/src/__tests__/validation.test.ts +3555 -0
- package/src/__tests__/view.test.ts +715 -0
- package/src/binding/__tests__/binding.test.ts +113 -0
- package/src/binding/__tests__/index.test.ts +208 -0
- package/src/binding/__tests__/resolver.test.ts +83 -0
- package/src/binding/binding.ts +6 -6
- package/src/binding/index.ts +34 -34
- package/src/binding/resolver.ts +19 -19
- package/src/binding/utils.ts +7 -7
- package/src/binding-grammar/__tests__/parser.test.ts +64 -0
- package/src/binding-grammar/__tests__/test-utils/ast-cases.ts +198 -0
- package/src/binding-grammar/__tests__/test-utils/perf-test.ts +66 -0
- package/src/binding-grammar/ast.ts +11 -11
- package/src/binding-grammar/custom/index.ts +19 -22
- package/src/binding-grammar/ebnf/index.ts +20 -21
- package/src/binding-grammar/ebnf/types.ts +13 -13
- package/src/binding-grammar/index.ts +4 -4
- package/src/binding-grammar/parsimmon/index.ts +14 -14
- package/src/controllers/constants/__tests__/index.test.ts +106 -0
- package/src/controllers/constants/index.ts +3 -3
- package/src/controllers/constants/utils.ts +4 -4
- package/src/controllers/data/controller.ts +22 -22
- package/src/controllers/data/index.ts +1 -1
- package/src/controllers/data/utils.ts +7 -7
- package/src/controllers/flow/__tests__/controller.test.ts +195 -0
- package/src/controllers/flow/__tests__/flow.test.ts +381 -0
- package/src/controllers/flow/controller.ts +13 -13
- package/src/controllers/flow/flow.ts +23 -23
- package/src/controllers/flow/index.ts +2 -2
- package/src/controllers/index.ts +5 -5
- package/src/controllers/validation/binding-tracker.ts +71 -59
- package/src/controllers/validation/controller.ts +104 -104
- package/src/controllers/validation/index.ts +2 -2
- package/src/controllers/view/asset-transform.ts +20 -20
- package/src/controllers/view/controller.ts +27 -27
- package/src/controllers/view/index.ts +4 -4
- package/src/controllers/view/store.ts +3 -3
- package/src/controllers/view/types.ts +7 -7
- package/src/data/__tests__/__snapshots__/dependency-tracker.test.ts.snap +64 -0
- package/src/data/__tests__/dependency-tracker.test.ts +146 -0
- package/src/data/__tests__/local-model.test.ts +46 -0
- package/src/data/__tests__/model.test.ts +78 -0
- package/src/data/dependency-tracker.ts +16 -16
- package/src/data/index.ts +4 -4
- package/src/data/local-model.ts +6 -6
- package/src/data/model.ts +17 -17
- package/src/data/noop-model.ts +1 -1
- package/src/expressions/__tests__/__snapshots__/parser.test.ts.snap +854 -0
- package/src/expressions/__tests__/evaluator-functions.test.ts +47 -0
- package/src/expressions/__tests__/evaluator.test.ts +410 -0
- package/src/expressions/__tests__/parser.test.ts +115 -0
- package/src/expressions/__tests__/utils.test.ts +44 -0
- package/src/expressions/evaluator-functions.ts +6 -6
- package/src/expressions/evaluator.ts +71 -67
- package/src/expressions/index.ts +4 -4
- package/src/expressions/parser.ts +102 -105
- package/src/expressions/types.ts +29 -21
- package/src/expressions/utils.ts +32 -21
- package/src/index.ts +13 -13
- package/src/logger/__tests__/consoleLogger.test.ts +46 -0
- package/src/logger/__tests__/noopLogger.test.ts +13 -0
- package/src/logger/__tests__/proxyLogger.test.ts +31 -0
- package/src/logger/__tests__/tapableLogger.test.ts +41 -0
- package/src/logger/consoleLogger.ts +9 -9
- package/src/logger/index.ts +5 -5
- package/src/logger/noopLogger.ts +1 -1
- package/src/logger/proxyLogger.ts +6 -6
- package/src/logger/tapableLogger.ts +7 -7
- package/src/logger/types.ts +2 -2
- package/src/player.ts +60 -58
- package/src/plugins/default-exp-plugin.ts +10 -10
- package/src/plugins/default-view-plugin.ts +29 -0
- package/src/plugins/flow-exp-plugin.ts +6 -6
- package/src/schema/__tests__/schema.test.ts +243 -0
- package/src/schema/index.ts +2 -2
- package/src/schema/schema.ts +24 -24
- package/src/schema/types.ts +4 -4
- package/src/string-resolver/__tests__/index.test.ts +361 -0
- package/src/string-resolver/index.ts +17 -17
- package/src/types.ts +17 -17
- package/src/utils/__tests__/replaceParams.test.ts +33 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/replaceParams.ts +1 -1
- package/src/validator/__tests__/binding-map-splice.test.ts +53 -0
- package/src/validator/__tests__/validation-middleware.test.ts +127 -0
- package/src/validator/binding-map-splice.ts +5 -5
- package/src/validator/index.ts +4 -4
- package/src/validator/registry.ts +1 -1
- package/src/validator/types.ts +13 -13
- package/src/validator/validation-middleware.ts +15 -15
- package/src/view/__tests__/view.immutable.test.ts +269 -0
- package/src/view/__tests__/view.test.ts +959 -0
- package/src/view/builder/index.test.ts +69 -0
- package/src/view/builder/index.ts +3 -3
- package/src/view/index.ts +5 -5
- package/src/view/parser/__tests__/__snapshots__/parser.test.ts.snap +394 -0
- package/src/view/parser/__tests__/parser.test.ts +264 -0
- package/src/view/parser/index.ts +43 -33
- package/src/view/parser/types.ts +11 -11
- package/src/view/parser/utils.ts +5 -5
- package/src/view/plugins/__tests__/__snapshots__/template.test.ts.snap +278 -0
- package/src/view/plugins/__tests__/applicability.test.ts +265 -0
- package/src/view/plugins/__tests__/string.test.ts +122 -0
- package/src/view/plugins/__tests__/template.test.ts +724 -0
- package/src/view/plugins/applicability.ts +19 -19
- package/src/view/plugins/index.ts +4 -5
- package/src/view/plugins/options.ts +1 -1
- package/src/view/plugins/string-resolver.ts +22 -22
- package/src/view/plugins/switch.ts +22 -23
- package/src/view/plugins/template-plugin.ts +26 -27
- package/src/view/resolver/__tests__/dependencies.test.ts +321 -0
- package/src/view/resolver/__tests__/edgecases.test.ts +626 -0
- package/src/view/resolver/index.ts +42 -42
- package/src/view/resolver/types.ts +21 -20
- package/src/view/resolver/utils.ts +9 -9
- package/src/view/view.ts +32 -22
- package/types/binding/binding.d.ts +50 -0
- package/types/binding/index.d.ts +29 -0
- package/types/binding/resolver.d.ts +26 -0
- package/types/binding/utils.d.ts +12 -0
- package/types/binding-grammar/ast.d.ts +67 -0
- package/types/binding-grammar/custom/index.d.ts +4 -0
- package/types/binding-grammar/ebnf/index.d.ts +4 -0
- package/types/binding-grammar/ebnf/types.d.ts +75 -0
- package/types/binding-grammar/index.d.ts +5 -0
- package/types/binding-grammar/parsimmon/index.d.ts +4 -0
- package/types/controllers/constants/index.d.ts +45 -0
- package/types/controllers/constants/utils.d.ts +6 -0
- package/types/controllers/data/controller.d.ts +45 -0
- package/types/controllers/data/index.d.ts +2 -0
- package/types/controllers/data/utils.d.ts +14 -0
- package/types/controllers/flow/controller.d.ts +25 -0
- package/types/controllers/flow/flow.d.ts +50 -0
- package/types/controllers/flow/index.d.ts +3 -0
- package/types/controllers/index.d.ts +6 -0
- package/types/controllers/validation/binding-tracker.d.ts +32 -0
- package/types/controllers/validation/controller.d.ts +151 -0
- package/types/controllers/validation/index.d.ts +3 -0
- package/types/controllers/view/asset-transform.d.ts +19 -0
- package/types/controllers/view/controller.d.ts +37 -0
- package/types/controllers/view/index.d.ts +5 -0
- package/types/controllers/view/store.d.ts +20 -0
- package/types/controllers/view/types.d.ts +16 -0
- package/types/data/dependency-tracker.d.ts +49 -0
- package/types/data/index.d.ts +5 -0
- package/types/data/local-model.d.ts +16 -0
- package/types/data/model.d.ts +86 -0
- package/types/data/noop-model.d.ts +13 -0
- package/types/expressions/evaluator-functions.d.ts +15 -0
- package/types/expressions/evaluator.d.ts +52 -0
- package/types/expressions/index.d.ts +5 -0
- package/types/expressions/parser.d.ts +10 -0
- package/types/expressions/types.d.ts +144 -0
- package/types/expressions/utils.d.ts +12 -0
- package/types/index.d.ts +14 -0
- package/types/logger/consoleLogger.d.ts +17 -0
- package/types/logger/index.d.ts +6 -0
- package/types/logger/noopLogger.d.ts +10 -0
- package/types/logger/proxyLogger.d.ts +15 -0
- package/types/logger/tapableLogger.d.ts +23 -0
- package/types/logger/types.d.ts +6 -0
- package/types/player.d.ts +101 -0
- package/types/plugins/default-exp-plugin.d.ts +9 -0
- package/types/plugins/default-view-plugin.d.ts +9 -0
- package/types/plugins/flow-exp-plugin.d.ts +11 -0
- package/types/schema/index.d.ts +3 -0
- package/types/schema/schema.d.ts +36 -0
- package/types/schema/types.d.ts +38 -0
- package/types/string-resolver/index.d.ts +30 -0
- package/types/types.d.ts +73 -0
- package/types/utils/index.d.ts +2 -0
- package/types/utils/replaceParams.d.ts +9 -0
- package/types/validator/binding-map-splice.d.ts +10 -0
- package/types/validator/index.d.ts +5 -0
- package/types/validator/registry.d.ts +11 -0
- package/types/validator/types.d.ts +53 -0
- package/types/validator/validation-middleware.d.ts +36 -0
- package/types/view/builder/index.d.ts +35 -0
- package/types/view/index.d.ts +6 -0
- package/types/view/parser/index.d.ts +52 -0
- package/types/view/parser/types.d.ts +109 -0
- package/types/view/parser/utils.d.ts +6 -0
- package/types/view/plugins/applicability.d.ts +10 -0
- package/types/view/plugins/index.d.ts +5 -0
- package/types/view/plugins/options.d.ts +4 -0
- package/types/view/plugins/string-resolver.d.ts +13 -0
- package/types/view/plugins/switch.d.ts +14 -0
- package/types/view/plugins/template-plugin.d.ts +33 -0
- package/types/view/resolver/index.d.ts +73 -0
- package/types/view/resolver/types.d.ts +129 -0
- package/types/view/resolver/utils.d.ts +11 -0
- package/types/view/view.d.ts +37 -0
- package/dist/index.d.ts +0 -1814
- package/dist/player.dev.js +0 -11472
- package/dist/player.prod.js +0 -2
- package/src/view/plugins/plugin.ts +0 -21
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { SyncWaterfallHook, SyncHook } from
|
|
2
|
-
import { setIn, addLast, clone } from
|
|
3
|
-
import dlv from
|
|
4
|
-
import { dequal } from
|
|
5
|
-
import type { BindingInstance, BindingLike } from
|
|
1
|
+
import { SyncWaterfallHook, SyncHook } from "tapable-ts";
|
|
2
|
+
import { setIn, addLast, clone } from "timm";
|
|
3
|
+
import dlv from "dlv";
|
|
4
|
+
import { dequal } from "dequal";
|
|
5
|
+
import type { BindingInstance, BindingLike } from "../../binding";
|
|
6
6
|
import type {
|
|
7
7
|
DataModelOptions,
|
|
8
8
|
DataModelWithParser,
|
|
9
9
|
Updates,
|
|
10
|
-
} from
|
|
11
|
-
import { DependencyModel, withParser } from
|
|
12
|
-
import type { Logger } from
|
|
13
|
-
import type { Node } from
|
|
14
|
-
import { NodeType } from
|
|
10
|
+
} from "../../data";
|
|
11
|
+
import { DependencyModel, withParser } from "../../data";
|
|
12
|
+
import type { Logger } from "../../logger";
|
|
13
|
+
import type { Node } from "../parser";
|
|
14
|
+
import { NodeType } from "../parser";
|
|
15
15
|
import {
|
|
16
16
|
caresAboutDataChanges,
|
|
17
17
|
toNodeResolveOptions,
|
|
18
18
|
unpackAndPush,
|
|
19
|
-
} from
|
|
20
|
-
import type { Resolve } from
|
|
21
|
-
import { getNodeID } from
|
|
19
|
+
} from "./utils";
|
|
20
|
+
import type { Resolve } from "./types";
|
|
21
|
+
import { getNodeID } from "../parser/utils";
|
|
22
22
|
|
|
23
|
-
export * from
|
|
24
|
-
export * from
|
|
23
|
+
export * from "./types";
|
|
24
|
+
export * from "./utils";
|
|
25
25
|
|
|
26
26
|
interface NodeUpdate extends Resolve.ResolvedNode {
|
|
27
27
|
/** A flag to track if a node has changed since the last resolution */
|
|
@@ -40,7 +40,7 @@ const withContext = (model: DataModelWithParser): DataModelWithParser => {
|
|
|
40
40
|
|
|
41
41
|
set: (
|
|
42
42
|
transaction: [BindingLike, any][],
|
|
43
|
-
options?: DataModelOptions
|
|
43
|
+
options?: DataModelOptions,
|
|
44
44
|
): Updates => {
|
|
45
45
|
return model.set(transaction, {
|
|
46
46
|
context: { model },
|
|
@@ -163,7 +163,7 @@ export class Resolver {
|
|
|
163
163
|
resolveCache,
|
|
164
164
|
toNodeResolveOptions(this.options),
|
|
165
165
|
undefined,
|
|
166
|
-
prevASTMap
|
|
166
|
+
prevASTMap,
|
|
167
167
|
);
|
|
168
168
|
this.resolveCache = resolveCache;
|
|
169
169
|
this.hooks.afterUpdate.call(updated.value);
|
|
@@ -190,11 +190,11 @@ export class Resolver {
|
|
|
190
190
|
if (isFirstUpdate) {
|
|
191
191
|
if (node.type === NodeType.Asset || node.type === NodeType.View) {
|
|
192
192
|
this.logger?.error(
|
|
193
|
-
`Cache conflict: Found Asset/View nodes that have conflicting ids: ${id}, may cause cache issues
|
|
193
|
+
`Cache conflict: Found Asset/View nodes that have conflicting ids: ${id}, may cause cache issues.`,
|
|
194
194
|
);
|
|
195
195
|
} else if (node.type === NodeType.Value) {
|
|
196
196
|
this.logger?.info(
|
|
197
|
-
`Cache conflict: Found Value nodes that have conflicting ids: ${id}, may cause cache issues. To improve performance make value node IDs globally unique
|
|
197
|
+
`Cache conflict: Found Value nodes that have conflicting ids: ${id}, may cause cache issues. To improve performance make value node IDs globally unique.`,
|
|
198
198
|
);
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -213,10 +213,10 @@ export class Resolver {
|
|
|
213
213
|
const clonedNode = clone(node);
|
|
214
214
|
|
|
215
215
|
Object.keys(clonedNode).forEach((key) => {
|
|
216
|
-
if (key ===
|
|
216
|
+
if (key === "parent") return;
|
|
217
217
|
|
|
218
218
|
const value = clonedNode[key];
|
|
219
|
-
if (typeof value ===
|
|
219
|
+
if (typeof value === "object" && value !== null) {
|
|
220
220
|
clonedNode[key] = Array.isArray(value) ? [...value] : { ...value };
|
|
221
221
|
}
|
|
222
222
|
});
|
|
@@ -231,13 +231,13 @@ export class Resolver {
|
|
|
231
231
|
cacheUpdate: Map<Node.Node, Resolve.ResolvedNode>,
|
|
232
232
|
options: Resolve.NodeResolveOptions,
|
|
233
233
|
partiallyResolvedParent: Node.Node | undefined,
|
|
234
|
-
prevASTMap: Map<Node.Node, Node.Node
|
|
234
|
+
prevASTMap: Map<Node.Node, Node.Node>,
|
|
235
235
|
): NodeUpdate {
|
|
236
236
|
const dependencyModel = new DependencyModel(options.data.model);
|
|
237
237
|
|
|
238
|
-
dependencyModel.trackSubset(
|
|
238
|
+
dependencyModel.trackSubset("core");
|
|
239
239
|
const depModelWithParser = withContext(
|
|
240
|
-
withParser(dependencyModel, this.options.parseBinding)
|
|
240
|
+
withParser(dependencyModel, this.options.parseBinding),
|
|
241
241
|
);
|
|
242
242
|
|
|
243
243
|
const resolveOptions = this.hooks.resolveOptions.call(
|
|
@@ -251,7 +251,7 @@ export class Resolver {
|
|
|
251
251
|
this.options.evaluator.evaluate(exp, { model: depModelWithParser }),
|
|
252
252
|
node,
|
|
253
253
|
},
|
|
254
|
-
node
|
|
254
|
+
node,
|
|
255
255
|
);
|
|
256
256
|
|
|
257
257
|
const previousResult = this.getPreviousResult(node);
|
|
@@ -261,7 +261,7 @@ export class Resolver {
|
|
|
261
261
|
const shouldUseLastValue = this.hooks.skipResolve.call(
|
|
262
262
|
!dataChanged,
|
|
263
263
|
node,
|
|
264
|
-
resolveOptions
|
|
264
|
+
resolveOptions,
|
|
265
265
|
);
|
|
266
266
|
|
|
267
267
|
// Shallow clone the node so that changes to it during the resolve steps don't impact the original.
|
|
@@ -272,7 +272,7 @@ export class Resolver {
|
|
|
272
272
|
};
|
|
273
273
|
const resolvedAST = this.hooks.beforeResolve.call(
|
|
274
274
|
clonedNode,
|
|
275
|
-
resolveOptions
|
|
275
|
+
resolveOptions,
|
|
276
276
|
) ?? {
|
|
277
277
|
type: NodeType.Empty,
|
|
278
278
|
};
|
|
@@ -292,7 +292,7 @@ export class Resolver {
|
|
|
292
292
|
const repopulateASTMapFromCache = (
|
|
293
293
|
resolvedNode: Resolve.ResolvedNode,
|
|
294
294
|
AST: Node.Node,
|
|
295
|
-
ASTParent: Node.Node | undefined
|
|
295
|
+
ASTParent: Node.Node | undefined,
|
|
296
296
|
) => {
|
|
297
297
|
const { node: resolvedASTLocal } = resolvedNode;
|
|
298
298
|
this.ASTMap.set(resolvedASTLocal, AST);
|
|
@@ -312,13 +312,13 @@ export class Resolver {
|
|
|
312
312
|
repopulateASTMapFromCache(
|
|
313
313
|
previousChildResult,
|
|
314
314
|
originalChildNode,
|
|
315
|
-
AST
|
|
315
|
+
AST,
|
|
316
316
|
);
|
|
317
317
|
};
|
|
318
318
|
|
|
319
|
-
if (
|
|
319
|
+
if ("children" in resolvedASTLocal) {
|
|
320
320
|
resolvedASTLocal.children?.forEach(({ value: childAST }) =>
|
|
321
|
-
handleChildNode(childAST)
|
|
321
|
+
handleChildNode(childAST),
|
|
322
322
|
);
|
|
323
323
|
} else if (resolvedASTLocal.type === NodeType.MultiNode) {
|
|
324
324
|
resolvedASTLocal.values.forEach(handleChildNode);
|
|
@@ -344,7 +344,7 @@ export class Resolver {
|
|
|
344
344
|
let resolved = this.hooks.resolve.call(
|
|
345
345
|
undefined,
|
|
346
346
|
resolvedAST,
|
|
347
|
-
resolveOptions
|
|
347
|
+
resolveOptions,
|
|
348
348
|
);
|
|
349
349
|
|
|
350
350
|
let updated = !dequal(previousResult?.value, resolved);
|
|
@@ -354,9 +354,9 @@ export class Resolver {
|
|
|
354
354
|
}
|
|
355
355
|
|
|
356
356
|
const childDependencies = new Set<BindingInstance>();
|
|
357
|
-
dependencyModel.trackSubset(
|
|
357
|
+
dependencyModel.trackSubset("children");
|
|
358
358
|
|
|
359
|
-
if (
|
|
359
|
+
if ("children" in resolvedAST) {
|
|
360
360
|
const newChildren = resolvedAST.children?.map((child) => {
|
|
361
361
|
const computedChildTree = this.computeTree(
|
|
362
362
|
child.value,
|
|
@@ -365,7 +365,7 @@ export class Resolver {
|
|
|
365
365
|
cacheUpdate,
|
|
366
366
|
resolveOptions,
|
|
367
367
|
resolvedAST,
|
|
368
|
-
prevASTMap
|
|
368
|
+
prevASTMap,
|
|
369
369
|
);
|
|
370
370
|
const {
|
|
371
371
|
dependencies: childTreeDeps,
|
|
@@ -380,7 +380,7 @@ export class Resolver {
|
|
|
380
380
|
if (childNode.type === NodeType.MultiNode && !childNode.override) {
|
|
381
381
|
const arr = addLast(
|
|
382
382
|
dlv(resolved, child.path as any[], []),
|
|
383
|
-
childValue
|
|
383
|
+
childValue,
|
|
384
384
|
);
|
|
385
385
|
resolved = setIn(resolved, child.path, arr);
|
|
386
386
|
} else {
|
|
@@ -408,7 +408,7 @@ export class Resolver {
|
|
|
408
408
|
cacheUpdate,
|
|
409
409
|
resolveOptions,
|
|
410
410
|
resolvedAST,
|
|
411
|
-
prevASTMap
|
|
411
|
+
prevASTMap,
|
|
412
412
|
);
|
|
413
413
|
|
|
414
414
|
if (mTree.value !== undefined && mTree.value !== null) {
|
|
@@ -425,7 +425,7 @@ export class Resolver {
|
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
mTree.dependencies.forEach((bindingDep) =>
|
|
428
|
-
childDependencies.add(bindingDep)
|
|
428
|
+
childDependencies.add(bindingDep),
|
|
429
429
|
);
|
|
430
430
|
|
|
431
431
|
updated = updated || mTree.updated;
|
|
@@ -438,17 +438,17 @@ export class Resolver {
|
|
|
438
438
|
}
|
|
439
439
|
|
|
440
440
|
childDependencies.forEach((bindingDep) =>
|
|
441
|
-
dependencyModel.addChildReadDep(bindingDep)
|
|
441
|
+
dependencyModel.addChildReadDep(bindingDep),
|
|
442
442
|
);
|
|
443
443
|
|
|
444
|
-
dependencyModel.trackSubset(
|
|
444
|
+
dependencyModel.trackSubset("core");
|
|
445
445
|
if (previousResult && !updated) {
|
|
446
446
|
resolved = previousResult?.value;
|
|
447
447
|
}
|
|
448
448
|
|
|
449
449
|
resolved = this.hooks.afterResolve.call(resolved, resolvedAST, {
|
|
450
450
|
...resolveOptions,
|
|
451
|
-
getDependencies: (scope?:
|
|
451
|
+
getDependencies: (scope?: "core" | "children") =>
|
|
452
452
|
dependencyModel.getDependencies(scope),
|
|
453
453
|
});
|
|
454
454
|
|
|
@@ -465,7 +465,7 @@ export class Resolver {
|
|
|
465
465
|
this.hooks.afterNodeUpdate.call(
|
|
466
466
|
node,
|
|
467
467
|
isNestedMultiNode ? partiallyResolvedParent?.parent : rawParent,
|
|
468
|
-
update
|
|
468
|
+
update,
|
|
469
469
|
);
|
|
470
470
|
cacheUpdate.set(node, update);
|
|
471
471
|
|
|
@@ -2,24 +2,24 @@ import type {
|
|
|
2
2
|
Schema,
|
|
3
3
|
Formatting,
|
|
4
4
|
Validation as ValidationTypes,
|
|
5
|
-
} from
|
|
5
|
+
} from "@player-ui/types";
|
|
6
6
|
import type {
|
|
7
7
|
BindingInstance,
|
|
8
8
|
BindingLike,
|
|
9
9
|
BindingFactory,
|
|
10
|
-
} from
|
|
10
|
+
} from "../../binding";
|
|
11
11
|
import type {
|
|
12
12
|
DataModelWithParser,
|
|
13
13
|
DataModelImpl,
|
|
14
14
|
DataModelOptions,
|
|
15
|
-
} from
|
|
16
|
-
import type { ConstantsProvider } from
|
|
17
|
-
import type { TransitionFunction } from
|
|
18
|
-
import type { ExpressionEvaluator, ExpressionType } from
|
|
19
|
-
import type { ValidationResponse } from
|
|
20
|
-
import type { Logger } from
|
|
21
|
-
import type { SchemaController } from
|
|
22
|
-
import type { Node } from
|
|
15
|
+
} from "../../data";
|
|
16
|
+
import type { ConstantsProvider } from "../../controllers/constants";
|
|
17
|
+
import type { TransitionFunction } from "../../controllers";
|
|
18
|
+
import type { ExpressionEvaluator, ExpressionType } from "../../expressions";
|
|
19
|
+
import type { ValidationResponse } from "../../validator";
|
|
20
|
+
import type { Logger } from "../../logger";
|
|
21
|
+
import type { SchemaController } from "../../schema";
|
|
22
|
+
import type { Node } from "../parser";
|
|
23
23
|
|
|
24
24
|
export interface ValidationGetResolveOptions {
|
|
25
25
|
/**
|
|
@@ -33,6 +33,7 @@ export interface PlayerUtils {
|
|
|
33
33
|
findPlugin<Plugin = unknown>(symbol: symbol): Plugin | undefined;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
36
37
|
export declare namespace Resolve {
|
|
37
38
|
export interface Validation {
|
|
38
39
|
/** Fetch the data-type for the given binding */
|
|
@@ -40,7 +41,7 @@ export declare namespace Resolve {
|
|
|
40
41
|
|
|
41
42
|
/** Get all currently applicable validation errors */
|
|
42
43
|
getAll(
|
|
43
|
-
options?: ValidationGetResolveOptions
|
|
44
|
+
options?: ValidationGetResolveOptions,
|
|
44
45
|
): Map<BindingInstance, ValidationResponse> | undefined;
|
|
45
46
|
|
|
46
47
|
/** Internal Method to lookup if there is a validation for the given binding */
|
|
@@ -48,12 +49,12 @@ export declare namespace Resolve {
|
|
|
48
49
|
| {
|
|
49
50
|
/** Get the validation for the given binding */
|
|
50
51
|
get: (
|
|
51
|
-
options?: ValidationGetResolveOptions
|
|
52
|
+
options?: ValidationGetResolveOptions,
|
|
52
53
|
) => ValidationResponse | undefined;
|
|
53
54
|
|
|
54
55
|
/** Get all validations for the given binding */
|
|
55
56
|
getAll: (
|
|
56
|
-
options?: ValidationGetResolveOptions
|
|
57
|
+
options?: ValidationGetResolveOptions,
|
|
57
58
|
) => Array<ValidationResponse>;
|
|
58
59
|
}
|
|
59
60
|
| undefined;
|
|
@@ -64,7 +65,7 @@ export declare namespace Resolve {
|
|
|
64
65
|
options?: {
|
|
65
66
|
/** If this binding should also be tracked for validations */
|
|
66
67
|
track?: boolean;
|
|
67
|
-
} & ValidationGetResolveOptions
|
|
68
|
+
} & ValidationGetResolveOptions,
|
|
68
69
|
): ValidationResponse | undefined;
|
|
69
70
|
|
|
70
71
|
getValidationsForBinding(
|
|
@@ -72,12 +73,12 @@ export declare namespace Resolve {
|
|
|
72
73
|
options?: {
|
|
73
74
|
/** If this binding should also be tracked for validations */
|
|
74
75
|
track?: boolean;
|
|
75
|
-
} & ValidationGetResolveOptions
|
|
76
|
+
} & ValidationGetResolveOptions,
|
|
76
77
|
): Array<ValidationResponse>;
|
|
77
78
|
|
|
78
79
|
/** Get errors for all children regardless of section */
|
|
79
80
|
getChildren(
|
|
80
|
-
type?: ValidationTypes.DisplayTarget
|
|
81
|
+
type?: ValidationTypes.DisplayTarget,
|
|
81
82
|
): Array<ValidationResponse>;
|
|
82
83
|
|
|
83
84
|
/** Get errors for all children solely in this section */
|
|
@@ -89,7 +90,7 @@ export declare namespace Resolve {
|
|
|
89
90
|
/** Register node as a section */
|
|
90
91
|
register: (options?: {
|
|
91
92
|
/** While type of Display Target group it should register as */
|
|
92
|
-
type: Exclude<ValidationTypes.DisplayTarget,
|
|
93
|
+
type: Exclude<ValidationTypes.DisplayTarget, "field">;
|
|
93
94
|
}) => void;
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -141,7 +142,7 @@ export declare namespace Resolve {
|
|
|
141
142
|
data: NodeDataOptions;
|
|
142
143
|
|
|
143
144
|
/** The data dependencies that were requested during the resolution */
|
|
144
|
-
getDependencies?(scope?:
|
|
145
|
+
getDependencies?(scope?: "core" | "children"): Set<BindingInstance>;
|
|
145
146
|
|
|
146
147
|
/** original node */
|
|
147
148
|
node?: Node.Node;
|
|
@@ -180,13 +181,13 @@ export declare namespace Resolve {
|
|
|
180
181
|
|
|
181
182
|
export type NodeTransformFunction = (
|
|
182
183
|
node: Node.Node,
|
|
183
|
-
options: NodeResolveOptions
|
|
184
|
+
options: NodeResolveOptions,
|
|
184
185
|
) => Node.Node | null;
|
|
185
186
|
|
|
186
187
|
export type NodeResolveFunction = (
|
|
187
188
|
value: any,
|
|
188
189
|
node: Node.Node,
|
|
189
|
-
options: NodeResolveOptions
|
|
190
|
+
options: NodeResolveOptions,
|
|
190
191
|
) => any;
|
|
191
192
|
|
|
192
193
|
export interface Plugin {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { BindingInstance, BindingLike } from
|
|
2
|
-
import { isBinding } from
|
|
3
|
-
import type { ExpressionType } from
|
|
4
|
-
import type { Resolve } from
|
|
1
|
+
import type { BindingInstance, BindingLike } from "../../binding";
|
|
2
|
+
import { isBinding } from "../../binding";
|
|
3
|
+
import type { ExpressionType } from "../../expressions";
|
|
4
|
+
import type { Resolve } from "./types";
|
|
5
5
|
|
|
6
6
|
/** Check to see if and of the data-changes affect the given dependencies */
|
|
7
7
|
export function caresAboutDataChanges(
|
|
8
8
|
dataChanges?: Set<BindingInstance>,
|
|
9
|
-
dependencies?: Set<BindingInstance
|
|
9
|
+
dependencies?: Set<BindingInstance>,
|
|
10
10
|
) {
|
|
11
11
|
if (!dataChanges || !dependencies) {
|
|
12
12
|
return true;
|
|
@@ -20,15 +20,15 @@ export function caresAboutDataChanges(
|
|
|
20
20
|
(dep) =>
|
|
21
21
|
!!dataChangeArray.find(
|
|
22
22
|
(change) =>
|
|
23
|
-
change === dep || change.contains(dep) || dep.contains(change)
|
|
24
|
-
)
|
|
23
|
+
change === dep || change.contains(dep) || dep.contains(change),
|
|
24
|
+
),
|
|
25
25
|
) !== undefined
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Convert the options object for a resolver to one for a node */
|
|
30
30
|
export function toNodeResolveOptions(
|
|
31
|
-
resolverOptions: Resolve.ResolverOptions
|
|
31
|
+
resolverOptions: Resolve.ResolverOptions,
|
|
32
32
|
): Resolve.NodeResolveOptions {
|
|
33
33
|
return {
|
|
34
34
|
...resolverOptions,
|
|
@@ -47,7 +47,7 @@ export function toNodeResolveOptions(
|
|
|
47
47
|
isBinding(bindingLike)
|
|
48
48
|
? bindingLike
|
|
49
49
|
: resolverOptions.parseBinding(bindingLike),
|
|
50
|
-
value
|
|
50
|
+
value,
|
|
51
51
|
)
|
|
52
52
|
: value,
|
|
53
53
|
},
|
package/src/view/view.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { SyncHook } from
|
|
2
|
-
import type { View as ViewType } from
|
|
3
|
-
import type { BindingInstance, BindingFactory } from
|
|
4
|
-
import type { ValidationProvider, ValidationObject } from
|
|
5
|
-
import type { Logger } from
|
|
6
|
-
import type { Resolve } from
|
|
7
|
-
import { Resolver, toNodeResolveOptions } from
|
|
8
|
-
import type { Node } from
|
|
9
|
-
import { Parser } from
|
|
1
|
+
import { SyncHook } from "tapable-ts";
|
|
2
|
+
import type { View as ViewType } from "@player-ui/types";
|
|
3
|
+
import type { BindingInstance, BindingFactory } from "../binding";
|
|
4
|
+
import type { ValidationProvider, ValidationObject } from "../validator";
|
|
5
|
+
import type { Logger } from "../logger";
|
|
6
|
+
import type { Resolve } from "./resolver";
|
|
7
|
+
import { Resolver, toNodeResolveOptions } from "./resolver";
|
|
8
|
+
import type { Node } from "./parser";
|
|
9
|
+
import { Parser } from "./parser";
|
|
10
10
|
import {
|
|
11
11
|
TemplatePlugin,
|
|
12
12
|
StringResolverPlugin,
|
|
13
13
|
ApplicabilityPlugin,
|
|
14
14
|
SwitchPlugin,
|
|
15
|
-
} from
|
|
15
|
+
} from "./plugins";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Manages the view level validations
|
|
@@ -36,7 +36,7 @@ class CrossfieldProvider implements ValidationProvider {
|
|
|
36
36
|
|
|
37
37
|
if (!Array.isArray(xfieldRefs)) {
|
|
38
38
|
this.logger?.warn(
|
|
39
|
-
`Unable to register view validations for id: ${contentView.id}. 'validation' property must be an Array
|
|
39
|
+
`Unable to register view validations for id: ${contentView.id}. 'validation' property must be an Array.`,
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
return;
|
|
@@ -49,8 +49,8 @@ class CrossfieldProvider implements ValidationProvider {
|
|
|
49
49
|
// x-field validations by default are triggered by navigating away from the page
|
|
50
50
|
// the reference can also override that _or_ the severity
|
|
51
51
|
const withDefaults: ValidationObject = {
|
|
52
|
-
trigger:
|
|
53
|
-
severity:
|
|
52
|
+
trigger: "navigation",
|
|
53
|
+
severity: "error",
|
|
54
54
|
...vRef,
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -83,6 +83,7 @@ export class ViewInstance implements ValidationProvider {
|
|
|
83
83
|
onUpdate: new SyncHook<[ViewType]>(),
|
|
84
84
|
parser: new SyncHook<[Parser]>(),
|
|
85
85
|
resolver: new SyncHook<[Resolver]>(),
|
|
86
|
+
onTemplatePluginCreated: new SyncHook<[TemplatePlugin]>(),
|
|
86
87
|
templatePlugin: new SyncHook<[TemplatePlugin]>(),
|
|
87
88
|
};
|
|
88
89
|
|
|
@@ -93,7 +94,7 @@ export class ViewInstance implements ValidationProvider {
|
|
|
93
94
|
|
|
94
95
|
private validationProvider?: CrossfieldProvider;
|
|
95
96
|
|
|
96
|
-
private templatePlugin: TemplatePlugin;
|
|
97
|
+
private templatePlugin: TemplatePlugin | undefined;
|
|
97
98
|
|
|
98
99
|
// TODO might want to add a version/timestamp to this to compare updates
|
|
99
100
|
public lastUpdate: Record<string, any> | undefined;
|
|
@@ -101,12 +102,9 @@ export class ViewInstance implements ValidationProvider {
|
|
|
101
102
|
constructor(initialView: ViewType, resolverOptions: Resolve.ResolverOptions) {
|
|
102
103
|
this.initialView = initialView;
|
|
103
104
|
this.resolverOptions = resolverOptions;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
new StringResolverPlugin().apply(this);
|
|
108
|
-
this.templatePlugin = new TemplatePlugin(pluginOptions);
|
|
109
|
-
this.templatePlugin.apply(this);
|
|
105
|
+
this.hooks.onTemplatePluginCreated.tap("view", (templatePlugin) => {
|
|
106
|
+
this.templatePlugin = templatePlugin;
|
|
107
|
+
});
|
|
110
108
|
}
|
|
111
109
|
|
|
112
110
|
public updateAsync() {
|
|
@@ -121,10 +119,16 @@ export class ViewInstance implements ValidationProvider {
|
|
|
121
119
|
this.validationProvider = new CrossfieldProvider(
|
|
122
120
|
this.initialView,
|
|
123
121
|
this.resolverOptions.parseBinding,
|
|
124
|
-
this.resolverOptions.logger
|
|
122
|
+
this.resolverOptions.logger,
|
|
125
123
|
);
|
|
126
124
|
|
|
127
|
-
|
|
125
|
+
if (this.templatePlugin) {
|
|
126
|
+
this.hooks.templatePlugin.call(this.templatePlugin);
|
|
127
|
+
} else {
|
|
128
|
+
this.resolverOptions.logger?.warn(
|
|
129
|
+
"templatePlugin not set for View, legacy templates may not work",
|
|
130
|
+
);
|
|
131
|
+
}
|
|
128
132
|
|
|
129
133
|
const parser = new Parser();
|
|
130
134
|
this.hooks.parser.call(parser);
|
|
@@ -153,3 +157,9 @@ export class ViewInstance implements ValidationProvider {
|
|
|
153
157
|
return this.validationProvider?.getValidationsForBinding(binding);
|
|
154
158
|
}
|
|
155
159
|
}
|
|
160
|
+
|
|
161
|
+
/** A plugin for a view */
|
|
162
|
+
export interface ViewPlugin {
|
|
163
|
+
/** Called with a view instance */
|
|
164
|
+
apply(view: ViewInstance): void;
|
|
165
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface BindingParserOptions {
|
|
2
|
+
/** Get the value for a specific binding */
|
|
3
|
+
get: (binding: BindingInstance) => any;
|
|
4
|
+
/**
|
|
5
|
+
* Set the values for bindings.
|
|
6
|
+
* This is used when the query syntax needs to modify an object
|
|
7
|
+
*/
|
|
8
|
+
set: (transaction: Array<[BindingInstance, any]>) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Get the result of evaluating an expression
|
|
11
|
+
*/
|
|
12
|
+
evaluate: (exp: string) => any;
|
|
13
|
+
/**
|
|
14
|
+
* Without readOnly, if a binding such as this is used: arr[key='does not exist'],
|
|
15
|
+
* then an object with that key will be created.
|
|
16
|
+
* This is done to make assignment such as arr[key='abc'].val = 'foo' work smoothly.
|
|
17
|
+
* Setting readOnly to true will prevent this behavior, avoiding unintended data changes.
|
|
18
|
+
*/
|
|
19
|
+
readOnly?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export type Getter = (path: BindingInstance) => any;
|
|
22
|
+
export type RawBindingSegment = number | string;
|
|
23
|
+
export type RawBinding = string | RawBindingSegment[];
|
|
24
|
+
export type BindingLike = RawBinding | BindingInstance;
|
|
25
|
+
export type BindingFactory = (raw: RawBinding, options?: Partial<BindingParserOptions>) => BindingInstance;
|
|
26
|
+
/**
|
|
27
|
+
* A path in the data model
|
|
28
|
+
*/
|
|
29
|
+
export declare class BindingInstance {
|
|
30
|
+
private split;
|
|
31
|
+
private joined;
|
|
32
|
+
private factory;
|
|
33
|
+
constructor(raw: RawBinding, factory?: (rawBinding: RawBinding) => BindingInstance);
|
|
34
|
+
asArray(): RawBindingSegment[];
|
|
35
|
+
asString(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Check to see if the given binding is a sub-path of the current one
|
|
38
|
+
*/
|
|
39
|
+
contains(binding: BindingInstance): boolean;
|
|
40
|
+
relative(binding: BindingInstance): RawBindingSegment[];
|
|
41
|
+
parent(): BindingInstance;
|
|
42
|
+
key(): RawBindingSegment;
|
|
43
|
+
/**
|
|
44
|
+
* This is a utility method to get a binding that is a descendent of this binding
|
|
45
|
+
*
|
|
46
|
+
* @param relative - The relative path to descend to
|
|
47
|
+
*/
|
|
48
|
+
descendent(relative: BindingLike): BindingInstance;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=binding.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SyncBailHook, SyncWaterfallHook } from "tapable-ts";
|
|
2
|
+
import type { AnyNode } from "../binding-grammar/index";
|
|
3
|
+
import type { BindingParserOptions, BindingLike } from "./binding";
|
|
4
|
+
import { BindingInstance } from "./binding";
|
|
5
|
+
import type { NormalizedResult, ResolveBindingASTOptions } from "./resolver";
|
|
6
|
+
export * from "./utils";
|
|
7
|
+
export * from "./binding";
|
|
8
|
+
export declare const SIMPLE_BINDING_REGEX: RegExp;
|
|
9
|
+
export declare const BINDING_BRACKETS_REGEX: RegExp;
|
|
10
|
+
type BeforeResolveNodeContext = Required<NormalizedResult> & ResolveBindingASTOptions;
|
|
11
|
+
/** A parser for creating bindings from a string */
|
|
12
|
+
export declare class BindingParser {
|
|
13
|
+
private cache;
|
|
14
|
+
private parseCache;
|
|
15
|
+
private parserOptions;
|
|
16
|
+
hooks: {
|
|
17
|
+
skipOptimization: SyncBailHook<[string], boolean, Record<string, any>>;
|
|
18
|
+
beforeResolveNode: SyncWaterfallHook<[AnyNode, BeforeResolveNodeContext], Record<string, any>>;
|
|
19
|
+
};
|
|
20
|
+
constructor(options?: Partial<BindingParserOptions>);
|
|
21
|
+
/**
|
|
22
|
+
* Takes a binding path, parses it, and returns an equivalent, normalized
|
|
23
|
+
* representation of that path.
|
|
24
|
+
*/
|
|
25
|
+
private normalizePath;
|
|
26
|
+
private getBindingForNormalizedResult;
|
|
27
|
+
parse(rawBinding: BindingLike, overrides?: Partial<BindingParserOptions>): BindingInstance;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SyncWaterfallHook } from "tapable-ts";
|
|
2
|
+
import type { PathNode, AnyNode } from "../binding-grammar";
|
|
3
|
+
export interface NormalizedResult {
|
|
4
|
+
/** The normalized path */
|
|
5
|
+
path: Array<string | number>;
|
|
6
|
+
/** Any new updates that need to happen for this binding to be resolved */
|
|
7
|
+
updates?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
export interface ResolveBindingASTOptions {
|
|
10
|
+
/** Get the value of the model at the given path */
|
|
11
|
+
getValue: (path: Array<string | number>) => any;
|
|
12
|
+
/** Convert the value into valid path segments */
|
|
13
|
+
convertToPath: (value: any) => string;
|
|
14
|
+
/** Convert the value into valid path segments */
|
|
15
|
+
evaluate: (exp: string) => any;
|
|
16
|
+
}
|
|
17
|
+
export interface ResolveBindingASTHooks {
|
|
18
|
+
/** A hook for transforming a node before fully resolving it */
|
|
19
|
+
beforeResolveNode: SyncWaterfallHook<[
|
|
20
|
+
AnyNode,
|
|
21
|
+
Required<NormalizedResult> & ResolveBindingASTOptions
|
|
22
|
+
]>;
|
|
23
|
+
}
|
|
24
|
+
/** Given a binding AST, resolve it */
|
|
25
|
+
export declare function resolveBindingAST(bindingPathNode: PathNode, options: ResolveBindingASTOptions, hooks?: ResolveBindingASTHooks): NormalizedResult;
|
|
26
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BindingLike, BindingInstance } from "./binding";
|
|
2
|
+
/** Check if the parameter representing a binding is already of the Binding class */
|
|
3
|
+
export declare function isBinding(binding: BindingLike): binding is BindingInstance;
|
|
4
|
+
/** Convert the string to an int if you can, otherwise just return the original string */
|
|
5
|
+
export declare function maybeConvertToNum(i: string): string | number;
|
|
6
|
+
/**
|
|
7
|
+
* utility to convert binding into binding segments.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getBindingSegments(binding: BindingLike): Array<string | number>;
|
|
10
|
+
/** Like _.findIndex, but ignores types */
|
|
11
|
+
export declare function findInArray<T extends Record<string | number, object>>(array: Array<T>, key: string | number, value: T): number | undefined;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|