@player-ui/player 0.3.0-next.2 → 0.3.0-next.4
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/index.cjs.js +4128 -891
- package/dist/index.d.ts +1227 -50
- package/dist/index.esm.js +4065 -836
- package/package.json +9 -15
- package/src/binding/binding.ts +108 -0
- package/src/binding/index.ts +188 -0
- package/src/binding/resolver.ts +157 -0
- package/src/binding/utils.ts +51 -0
- package/src/binding-grammar/ast.ts +113 -0
- package/src/binding-grammar/custom/index.ts +304 -0
- package/src/binding-grammar/ebnf/binding.ebnf +22 -0
- package/src/binding-grammar/ebnf/index.ts +186 -0
- package/src/binding-grammar/ebnf/types.ts +104 -0
- package/src/binding-grammar/index.ts +4 -0
- package/src/binding-grammar/parsimmon/index.ts +78 -0
- package/src/controllers/constants/index.ts +85 -0
- package/src/controllers/constants/utils.ts +37 -0
- package/src/{data.ts → controllers/data.ts} +6 -6
- package/src/controllers/flow/controller.ts +95 -0
- package/src/controllers/flow/flow.ts +205 -0
- package/src/controllers/flow/index.ts +2 -0
- package/src/controllers/index.ts +5 -0
- package/src/{validation → controllers/validation}/binding-tracker.ts +5 -5
- package/src/{validation → controllers/validation}/controller.ts +15 -14
- package/src/{validation → controllers/validation}/index.ts +0 -0
- package/src/{view → controllers/view}/asset-transform.ts +2 -3
- package/src/{view → controllers/view}/controller.ts +9 -8
- package/src/controllers/view/index.ts +4 -0
- package/src/{view → controllers/view}/store.ts +0 -0
- package/src/{view → controllers/view}/types.ts +2 -1
- package/src/data/dependency-tracker.ts +187 -0
- package/src/data/index.ts +4 -0
- package/src/data/local-model.ts +41 -0
- package/src/data/model.ts +216 -0
- package/src/data/noop-model.ts +18 -0
- package/src/expressions/evaluator-functions.ts +29 -0
- package/src/expressions/evaluator.ts +405 -0
- package/src/expressions/index.ts +3 -0
- package/src/expressions/parser.ts +889 -0
- package/src/expressions/types.ts +200 -0
- package/src/expressions/utils.ts +8 -0
- package/src/index.ts +9 -12
- package/src/logger/consoleLogger.ts +49 -0
- package/src/logger/index.ts +5 -0
- package/src/logger/noopLogger.ts +13 -0
- package/src/logger/proxyLogger.ts +25 -0
- package/src/logger/tapableLogger.ts +38 -0
- package/src/logger/types.ts +6 -0
- package/src/player.ts +21 -18
- package/src/plugins/flow-exp-plugin.ts +2 -3
- package/src/schema/index.ts +2 -0
- package/src/schema/schema.ts +220 -0
- package/src/schema/types.ts +60 -0
- package/src/string-resolver/index.ts +188 -0
- package/src/types.ts +11 -13
- package/src/utils/index.ts +1 -0
- package/src/utils/replaceParams.ts +17 -0
- package/src/validator/index.ts +3 -0
- package/src/validator/registry.ts +20 -0
- package/src/validator/types.ts +75 -0
- package/src/validator/validation-middleware.ts +114 -0
- package/src/view/builder/index.ts +81 -0
- package/src/view/index.ts +5 -4
- package/src/view/parser/index.ts +318 -0
- package/src/view/parser/types.ts +141 -0
- package/src/view/plugins/applicability.ts +78 -0
- package/src/view/plugins/index.ts +5 -0
- package/src/view/plugins/options.ts +4 -0
- package/src/view/plugins/plugin.ts +21 -0
- package/src/view/plugins/string-resolver.ts +149 -0
- package/src/view/plugins/switch.ts +120 -0
- package/src/view/plugins/template-plugin.ts +172 -0
- package/src/view/resolver/index.ts +397 -0
- package/src/view/resolver/types.ts +161 -0
- package/src/view/resolver/utils.ts +57 -0
- package/src/view/view.ts +149 -0
- package/src/utils/desc.d.ts +0 -2
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { BindingInstance } from '../binding';
|
|
2
|
+
import type {
|
|
3
|
+
BatchSetTransaction,
|
|
4
|
+
DataModelImpl,
|
|
5
|
+
DataModelMiddleware,
|
|
6
|
+
DataModelOptions,
|
|
7
|
+
Updates,
|
|
8
|
+
} from './model';
|
|
9
|
+
|
|
10
|
+
export type DependencySets = 'core' | 'children';
|
|
11
|
+
|
|
12
|
+
/** A class to track usage of read/writes to/from a data model */
|
|
13
|
+
export class DependencyTracker {
|
|
14
|
+
protected readDeps: Set<BindingInstance>;
|
|
15
|
+
protected writeDeps: Set<BindingInstance>;
|
|
16
|
+
protected namedSet: DependencySets;
|
|
17
|
+
|
|
18
|
+
private namedDependencySets: Partial<
|
|
19
|
+
Record<
|
|
20
|
+
DependencySets,
|
|
21
|
+
{
|
|
22
|
+
/** readDeps */
|
|
23
|
+
readDeps: Set<BindingInstance>;
|
|
24
|
+
/** writeDeps */
|
|
25
|
+
writeDeps: Set<BindingInstance>;
|
|
26
|
+
}
|
|
27
|
+
>
|
|
28
|
+
>;
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
this.readDeps = new Set();
|
|
32
|
+
this.writeDeps = new Set();
|
|
33
|
+
this.namedDependencySets = {};
|
|
34
|
+
this.namedSet = 'core';
|
|
35
|
+
|
|
36
|
+
this.createSubset('core');
|
|
37
|
+
this.createSubset('children');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
protected createSubset(name: DependencySets, force = false): void {
|
|
41
|
+
if (force || !this.namedDependencySets[name]) {
|
|
42
|
+
this.namedDependencySets[name] = {
|
|
43
|
+
readDeps: new Set(),
|
|
44
|
+
writeDeps: new Set(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Grab all of the bindings that this depended on */
|
|
50
|
+
public getDependencies(name?: DependencySets): Set<BindingInstance> {
|
|
51
|
+
if (name !== undefined) {
|
|
52
|
+
return this.namedDependencySets?.[name]?.readDeps ?? new Set();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return this.readDeps;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public trackSubset(name: DependencySets) {
|
|
59
|
+
this.createSubset(name);
|
|
60
|
+
this.namedSet = name;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public trackDefault() {
|
|
64
|
+
this.namedSet = 'core';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Grab all of the bindings this wrote to */
|
|
68
|
+
public getModified(name?: DependencySets): Set<BindingInstance> {
|
|
69
|
+
if (name !== undefined) {
|
|
70
|
+
return this.namedDependencySets?.[name]?.writeDeps ?? new Set();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return this.writeDeps;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check to see if the dataModel has read the value at the given binding
|
|
78
|
+
*
|
|
79
|
+
* @param binding - The binding you want to check for
|
|
80
|
+
*/
|
|
81
|
+
public readsBinding(binding: BindingInstance): boolean {
|
|
82
|
+
return this.readDeps.has(binding);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check to see if the dataModel has written to the binding
|
|
87
|
+
*/
|
|
88
|
+
public writesBinding(binding: BindingInstance): boolean {
|
|
89
|
+
return this.writeDeps.has(binding);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Reset all tracking of dependencies */
|
|
93
|
+
public reset() {
|
|
94
|
+
this.readDeps = new Set();
|
|
95
|
+
this.writeDeps = new Set();
|
|
96
|
+
this.namedDependencySets = {};
|
|
97
|
+
this.namedSet = 'core';
|
|
98
|
+
|
|
99
|
+
this.createSubset('core', true);
|
|
100
|
+
this.createSubset('children', true);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
protected addReadDep(
|
|
104
|
+
binding: BindingInstance,
|
|
105
|
+
namedSet = this.namedSet
|
|
106
|
+
): void {
|
|
107
|
+
if (namedSet) {
|
|
108
|
+
this.namedDependencySets?.[namedSet]?.readDeps.add(binding);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this.readDeps.add(binding);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected addWriteDep(
|
|
115
|
+
binding: BindingInstance,
|
|
116
|
+
namedSet = this.namedSet
|
|
117
|
+
): void {
|
|
118
|
+
if (namedSet) {
|
|
119
|
+
this.namedDependencySets?.[namedSet]?.writeDeps.add(binding);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.writeDeps.add(binding);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public addChildReadDep(binding: BindingInstance): void {
|
|
126
|
+
this.addReadDep(binding, 'children');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Middleware that tracks dependencies of read/written data */
|
|
131
|
+
export class DependencyMiddleware
|
|
132
|
+
extends DependencyTracker
|
|
133
|
+
implements DataModelMiddleware
|
|
134
|
+
{
|
|
135
|
+
constructor() {
|
|
136
|
+
super();
|
|
137
|
+
this.get = this.get.bind(this);
|
|
138
|
+
this.set = this.set.bind(this);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public set(
|
|
142
|
+
transaction: BatchSetTransaction,
|
|
143
|
+
options?: DataModelOptions,
|
|
144
|
+
next?: DataModelImpl | undefined
|
|
145
|
+
): Updates {
|
|
146
|
+
transaction.forEach(([binding]) => this.addWriteDep(binding));
|
|
147
|
+
|
|
148
|
+
return next?.set(transaction, options) ?? [];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public get(
|
|
152
|
+
binding: BindingInstance,
|
|
153
|
+
options?: DataModelOptions,
|
|
154
|
+
next?: DataModelImpl | undefined
|
|
155
|
+
) {
|
|
156
|
+
this.addReadDep(binding);
|
|
157
|
+
|
|
158
|
+
return next?.get(binding, options);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** A data-model that tracks dependencies of read/written data */
|
|
163
|
+
export class DependencyModel<Options = DataModelOptions>
|
|
164
|
+
extends DependencyTracker
|
|
165
|
+
implements DataModelImpl<Options>
|
|
166
|
+
{
|
|
167
|
+
private readonly rootModel: DataModelImpl<Options>;
|
|
168
|
+
|
|
169
|
+
constructor(rootModel: DataModelImpl<Options>) {
|
|
170
|
+
super();
|
|
171
|
+
this.rootModel = rootModel;
|
|
172
|
+
this.set = this.set.bind(this);
|
|
173
|
+
this.get = this.get.bind(this);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public set(transaction: BatchSetTransaction, options?: Options): Updates {
|
|
177
|
+
transaction.forEach(([binding]) => this.addWriteDep(binding));
|
|
178
|
+
|
|
179
|
+
return this.rootModel.set(transaction, options);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public get(binding: BindingInstance, options?: Options) {
|
|
183
|
+
this.addReadDep(binding);
|
|
184
|
+
|
|
185
|
+
return this.rootModel.get(binding, options);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import get from 'dlv';
|
|
2
|
+
import { setIn } from 'timm';
|
|
3
|
+
import type { BindingInstance } from '../binding';
|
|
4
|
+
import type { BatchSetTransaction, DataModelImpl, Updates } from './model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A data model that stores data in an in-memory JS object
|
|
8
|
+
*/
|
|
9
|
+
export class LocalModel implements DataModelImpl {
|
|
10
|
+
public model: {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
constructor(model = {}) {
|
|
15
|
+
this.model = model;
|
|
16
|
+
this.get = this.get.bind(this);
|
|
17
|
+
this.set = this.set.bind(this);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public reset(model = {}) {
|
|
21
|
+
this.model = model;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public get(binding?: BindingInstance) {
|
|
25
|
+
if (!binding || !binding.asString()) {
|
|
26
|
+
return this.model;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return get(this.model, binding.asArray() as string[]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public set(transaction: BatchSetTransaction) {
|
|
33
|
+
const effectiveOperations: Updates = [];
|
|
34
|
+
transaction.forEach(([binding, value]) => {
|
|
35
|
+
const oldValue = this.get(binding);
|
|
36
|
+
this.model = setIn(this.model, binding.asArray(), value) as any;
|
|
37
|
+
effectiveOperations.push({ binding, oldValue, newValue: value });
|
|
38
|
+
});
|
|
39
|
+
return effectiveOperations;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { SyncHook } from 'tapable-ts';
|
|
2
|
+
import type { BindingLike, BindingFactory } from '../binding';
|
|
3
|
+
import { BindingInstance, isBinding } from '../binding';
|
|
4
|
+
import { NOOP_MODEL } from './noop-model';
|
|
5
|
+
|
|
6
|
+
export const ROOT_BINDING = new BindingInstance([]);
|
|
7
|
+
export type BatchSetTransaction = [BindingInstance, any][];
|
|
8
|
+
|
|
9
|
+
export type Updates = Array<{
|
|
10
|
+
/** The updated binding */
|
|
11
|
+
binding: BindingInstance;
|
|
12
|
+
|
|
13
|
+
/** The old value */
|
|
14
|
+
oldValue: any;
|
|
15
|
+
|
|
16
|
+
/** The new value */
|
|
17
|
+
newValue: any;
|
|
18
|
+
|
|
19
|
+
/** Force the Update to be included even if no data changed */
|
|
20
|
+
force?: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
|
|
23
|
+
/** Options to use when getting or setting data */
|
|
24
|
+
export interface DataModelOptions {
|
|
25
|
+
/**
|
|
26
|
+
* The data (either to set or get) should represent a formatted value
|
|
27
|
+
* For setting data, the data will be de-formatted before continuing in the pipeline
|
|
28
|
+
* For getting data, the data will be formatted before returning
|
|
29
|
+
*/
|
|
30
|
+
formatted?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* By default, fetching data will ignore any invalid data.
|
|
34
|
+
* You can choose to grab the queued invalid data if you'd like
|
|
35
|
+
* This is usually the case for user-inputs
|
|
36
|
+
*/
|
|
37
|
+
includeInvalid?: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A flag to set to ignore any default value in the schema, and just use the raw value
|
|
41
|
+
*/
|
|
42
|
+
ignoreDefaultValue?: boolean;
|
|
43
|
+
|
|
44
|
+
/** Other context associated with this request */
|
|
45
|
+
context?: {
|
|
46
|
+
/** The data model to use when getting other data from the context of this request */
|
|
47
|
+
model: DataModelWithParser;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface DataModelWithParser<Options = DataModelOptions> {
|
|
52
|
+
get(binding: BindingLike, options?: Options): any;
|
|
53
|
+
set(transaction: [BindingLike, any][], options?: Options): Updates;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface DataModelImpl<Options = DataModelOptions> {
|
|
57
|
+
get(binding: BindingInstance, options?: Options): any;
|
|
58
|
+
set(transaction: BatchSetTransaction, options?: Options): Updates;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface DataModelMiddleware {
|
|
62
|
+
/** The name of the middleware */
|
|
63
|
+
name?: string;
|
|
64
|
+
|
|
65
|
+
set(
|
|
66
|
+
transaction: BatchSetTransaction,
|
|
67
|
+
options?: DataModelOptions,
|
|
68
|
+
next?: DataModelImpl
|
|
69
|
+
): Updates;
|
|
70
|
+
get(
|
|
71
|
+
binding: BindingInstance,
|
|
72
|
+
options?: DataModelOptions,
|
|
73
|
+
next?: DataModelImpl
|
|
74
|
+
): any;
|
|
75
|
+
reset?(): void;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Wrap the inputs of the DataModel with calls to parse raw binding inputs */
|
|
79
|
+
export function withParser<Options = unknown>(
|
|
80
|
+
model: DataModelImpl<Options>,
|
|
81
|
+
parseBinding: BindingFactory
|
|
82
|
+
): DataModelWithParser<Options> {
|
|
83
|
+
/** Parse something into a binding if it requires it */
|
|
84
|
+
function maybeParse(binding: BindingLike): BindingInstance {
|
|
85
|
+
const parsed = isBinding(binding)
|
|
86
|
+
? binding
|
|
87
|
+
: parseBinding(binding, {
|
|
88
|
+
get: model.get,
|
|
89
|
+
set: model.set,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (!parsed) {
|
|
93
|
+
throw new Error('Unable to parse binding');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return parsed;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
get(binding, options?: Options) {
|
|
101
|
+
return model.get(maybeParse(binding), options);
|
|
102
|
+
},
|
|
103
|
+
set(transaction, options?: Options) {
|
|
104
|
+
return model.set(
|
|
105
|
+
transaction.map(([key, val]) => [maybeParse(key), val]),
|
|
106
|
+
options
|
|
107
|
+
);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Wrap a middleware instance in a DataModel compliant API */
|
|
113
|
+
export function toModel(
|
|
114
|
+
middleware: DataModelMiddleware,
|
|
115
|
+
defaultOptions?: DataModelOptions,
|
|
116
|
+
next?: DataModelImpl
|
|
117
|
+
): DataModelImpl {
|
|
118
|
+
if (!next) {
|
|
119
|
+
return middleware as DataModelImpl;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
get: (binding: BindingInstance, options?: DataModelOptions) =>
|
|
124
|
+
middleware.get(binding, options ?? defaultOptions, next),
|
|
125
|
+
set: (transaction: BatchSetTransaction, options?: DataModelOptions) =>
|
|
126
|
+
middleware.set(transaction, options ?? defaultOptions, next),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type DataPipeline = Array<DataModelMiddleware | DataModelImpl>;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Given a set of steps in a pipeline, create the effective data-model
|
|
134
|
+
*/
|
|
135
|
+
export function constructModelForPipeline(
|
|
136
|
+
pipeline: DataPipeline
|
|
137
|
+
): DataModelImpl {
|
|
138
|
+
if (pipeline.length === 0) {
|
|
139
|
+
return NOOP_MODEL;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (pipeline.length === 1) {
|
|
143
|
+
return pipeline[0];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Default and propagate the options into the nested calls */
|
|
147
|
+
function createModelWithOptions(options?: DataModelOptions) {
|
|
148
|
+
const model: DataModelImpl =
|
|
149
|
+
pipeline.reduce<DataModelImpl | undefined>(
|
|
150
|
+
(nextModel, middleware) => toModel(middleware, options, nextModel),
|
|
151
|
+
undefined
|
|
152
|
+
) ?? NOOP_MODEL;
|
|
153
|
+
|
|
154
|
+
return model;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
get: (binding: BindingInstance, options?: DataModelOptions) => {
|
|
159
|
+
return createModelWithOptions(options)?.get(binding, options);
|
|
160
|
+
},
|
|
161
|
+
set: (transaction, options) => {
|
|
162
|
+
return createModelWithOptions(options)?.set(transaction, options);
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** A DataModel that manages middleware data handlers */
|
|
168
|
+
export class PipelinedDataModel implements DataModelImpl {
|
|
169
|
+
private pipeline: DataPipeline;
|
|
170
|
+
private effectiveDataModel: DataModelImpl;
|
|
171
|
+
|
|
172
|
+
public readonly hooks = {
|
|
173
|
+
onSet: new SyncHook<[BatchSetTransaction]>(),
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
constructor(pipeline: DataPipeline = []) {
|
|
177
|
+
this.pipeline = pipeline;
|
|
178
|
+
this.effectiveDataModel = constructModelForPipeline(this.pipeline);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public setMiddleware(handlers: DataPipeline) {
|
|
182
|
+
this.pipeline = handlers;
|
|
183
|
+
this.effectiveDataModel = constructModelForPipeline(handlers);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public addMiddleware(handler: DataModelMiddleware) {
|
|
187
|
+
this.pipeline = [...this.pipeline, handler];
|
|
188
|
+
this.effectiveDataModel = constructModelForPipeline(this.pipeline);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public reset(model = {}) {
|
|
192
|
+
this.pipeline.forEach((middleware) => {
|
|
193
|
+
if ('reset' in middleware) {
|
|
194
|
+
middleware.reset?.();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
this.set([[ROOT_BINDING, model]]);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public set(
|
|
202
|
+
transaction: BatchSetTransaction,
|
|
203
|
+
options?: DataModelOptions
|
|
204
|
+
): Updates {
|
|
205
|
+
const appliedTransaction = this.effectiveDataModel.set(
|
|
206
|
+
transaction,
|
|
207
|
+
options
|
|
208
|
+
);
|
|
209
|
+
this.hooks.onSet.call(transaction);
|
|
210
|
+
return appliedTransaction;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
public get(binding: BindingInstance, options?: DataModelOptions): any {
|
|
214
|
+
return this.effectiveDataModel.get(binding, options);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DataModelImpl } from './model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A model that does nothing
|
|
5
|
+
* Helpful for testing and other default DataModel applications
|
|
6
|
+
*/
|
|
7
|
+
export class NOOPDataModel implements DataModelImpl {
|
|
8
|
+
get() {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
set() {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** You only really need 1 instance of the NOOP model */
|
|
18
|
+
export const NOOP_MODEL = new NOOPDataModel();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Binding } from '@player-ui/types';
|
|
2
|
+
|
|
3
|
+
import type { BindingLike } from '../binding';
|
|
4
|
+
import type { ExpressionHandler, ExpressionContext } from './types';
|
|
5
|
+
|
|
6
|
+
/** Sets a value to the data-model */
|
|
7
|
+
export const setDataVal: ExpressionHandler<[Binding, any], any> = (
|
|
8
|
+
_context: ExpressionContext,
|
|
9
|
+
binding,
|
|
10
|
+
value
|
|
11
|
+
) => {
|
|
12
|
+
_context.model.set([[binding as BindingLike, value]]);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Fetches a valid from the data-model */
|
|
16
|
+
export const getDataVal: ExpressionHandler<[Binding], unknown> = (
|
|
17
|
+
_context: ExpressionContext,
|
|
18
|
+
binding
|
|
19
|
+
) => {
|
|
20
|
+
return _context.model.get(binding as BindingLike);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** Deletes a value from the model */
|
|
24
|
+
export const deleteDataVal: ExpressionHandler<[Binding], void> = (
|
|
25
|
+
_context: ExpressionContext,
|
|
26
|
+
binding
|
|
27
|
+
) => {
|
|
28
|
+
return _context.model.set([[binding as BindingLike, undefined]]);
|
|
29
|
+
};
|