@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
package/src/player.ts
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
import { setIn } from
|
|
2
|
-
import deferred from
|
|
3
|
-
import type { Flow as FlowType, FlowResult } from
|
|
4
|
-
|
|
5
|
-
import { SyncHook, SyncWaterfallHook } from
|
|
6
|
-
import type { Logger } from
|
|
7
|
-
import { TapableLogger } from
|
|
8
|
-
import type { ExpressionType } from
|
|
9
|
-
import { ExpressionEvaluator } from
|
|
10
|
-
import { SchemaController } from
|
|
11
|
-
import { BindingParser } from
|
|
12
|
-
import type { ViewInstance } from
|
|
13
|
-
import { resolveDataRefs } from
|
|
14
|
-
import type { FlowInstance } from
|
|
1
|
+
import { setIn } from "timm";
|
|
2
|
+
import deferred from "p-defer";
|
|
3
|
+
import type { Flow as FlowType, FlowResult } from "@player-ui/types";
|
|
4
|
+
|
|
5
|
+
import { SyncHook, SyncWaterfallHook } from "tapable-ts";
|
|
6
|
+
import type { Logger } from "./logger";
|
|
7
|
+
import { TapableLogger } from "./logger";
|
|
8
|
+
import type { ExpressionType } from "./expressions";
|
|
9
|
+
import { ExpressionEvaluator } from "./expressions";
|
|
10
|
+
import { SchemaController } from "./schema";
|
|
11
|
+
import { BindingParser } from "./binding";
|
|
12
|
+
import type { ViewInstance } from "./view";
|
|
13
|
+
import { resolveDataRefs } from "./string-resolver";
|
|
14
|
+
import type { FlowInstance } from "./controllers";
|
|
15
15
|
import {
|
|
16
16
|
ConstantsController,
|
|
17
17
|
ViewController,
|
|
18
18
|
DataController,
|
|
19
19
|
ValidationController,
|
|
20
20
|
FlowController,
|
|
21
|
-
} from
|
|
22
|
-
import { FlowExpPlugin } from
|
|
23
|
-
import { DefaultExpPlugin } from
|
|
21
|
+
} from "./controllers";
|
|
22
|
+
import { FlowExpPlugin } from "./plugins/flow-exp-plugin";
|
|
23
|
+
import { DefaultExpPlugin } from "./plugins/default-exp-plugin";
|
|
24
24
|
import type {
|
|
25
25
|
PlayerFlowState,
|
|
26
26
|
InProgressState,
|
|
27
27
|
CompletedState,
|
|
28
28
|
ErrorState,
|
|
29
|
-
} from
|
|
30
|
-
import { NOT_STARTED_STATE } from
|
|
29
|
+
} from "./types";
|
|
30
|
+
import { NOT_STARTED_STATE } from "./types";
|
|
31
|
+
import { DefaultViewPlugin } from "./plugins/default-view-plugin";
|
|
31
32
|
|
|
32
33
|
// Variables injected at build time
|
|
33
|
-
const PLAYER_VERSION =
|
|
34
|
-
const COMMIT =
|
|
34
|
+
const PLAYER_VERSION = "__VERSION__";
|
|
35
|
+
const COMMIT = "__GIT_COMMIT__";
|
|
35
36
|
|
|
36
37
|
export interface PlayerPlugin {
|
|
37
38
|
/**
|
|
@@ -58,7 +59,7 @@ export interface ExtendedPlayerPlugin<
|
|
|
58
59
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
59
60
|
Expressions = void,
|
|
60
61
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
|
-
DataTypes = void
|
|
62
|
+
DataTypes = void,
|
|
62
63
|
> {}
|
|
63
64
|
|
|
64
65
|
export interface PlayerConfigOptions {
|
|
@@ -136,6 +137,7 @@ export class Player {
|
|
|
136
137
|
this.config = config || {};
|
|
137
138
|
this.config.plugins = [
|
|
138
139
|
new DefaultExpPlugin(),
|
|
140
|
+
new DefaultViewPlugin(),
|
|
139
141
|
...(this.config.plugins || []),
|
|
140
142
|
new FlowExpPlugin(),
|
|
141
143
|
];
|
|
@@ -151,7 +153,7 @@ export class Player {
|
|
|
151
153
|
|
|
152
154
|
/** Find instance of [Plugin] that has been registered to Player */
|
|
153
155
|
public findPlugin<Plugin extends PlayerPlugin>(
|
|
154
|
-
symbol: symbol
|
|
156
|
+
symbol: symbol,
|
|
155
157
|
): Plugin | undefined {
|
|
156
158
|
return this.config.plugins?.find((el) => el.symbol === symbol) as Plugin;
|
|
157
159
|
}
|
|
@@ -159,7 +161,7 @@ export class Player {
|
|
|
159
161
|
/** Retrieve an instance of [Plugin] and conditionally invoke [apply] if it exists */
|
|
160
162
|
public applyTo<Plugin extends PlayerPlugin>(
|
|
161
163
|
symbol: symbol,
|
|
162
|
-
apply: (plugin: Plugin) => void
|
|
164
|
+
apply: (plugin: Plugin) => void,
|
|
163
165
|
): void {
|
|
164
166
|
const plugin = this.findPlugin<Plugin>(symbol);
|
|
165
167
|
|
|
@@ -208,7 +210,7 @@ export class Player {
|
|
|
208
210
|
start: () => void;
|
|
209
211
|
|
|
210
212
|
/** the state object to kick if off */
|
|
211
|
-
state: Omit<InProgressState,
|
|
213
|
+
state: Omit<InProgressState, "ref">;
|
|
212
214
|
} {
|
|
213
215
|
const userFlow = this.hooks.resolveFlowContent.call(userContent);
|
|
214
216
|
|
|
@@ -254,21 +256,21 @@ export class Player {
|
|
|
254
256
|
logger: this.logger,
|
|
255
257
|
});
|
|
256
258
|
|
|
257
|
-
dataController.hooks.format.tap(
|
|
259
|
+
dataController.hooks.format.tap("player", (value, binding) => {
|
|
258
260
|
const formatter = schema.getFormatter(binding);
|
|
259
261
|
|
|
260
262
|
return formatter ? formatter.format(value) : value;
|
|
261
263
|
});
|
|
262
264
|
|
|
263
|
-
dataController.hooks.deformat.tap(
|
|
265
|
+
dataController.hooks.deformat.tap("player", (value, binding) => {
|
|
264
266
|
const formatter = schema.getFormatter(binding);
|
|
265
267
|
|
|
266
268
|
return formatter ? formatter.deformat(value) : value;
|
|
267
269
|
});
|
|
268
270
|
|
|
269
271
|
dataController.hooks.resolveDefaultValue.tap(
|
|
270
|
-
|
|
271
|
-
(binding) => schema.getApparentType(binding)?.default
|
|
272
|
+
"player",
|
|
273
|
+
(binding) => schema.getApparentType(binding)?.default,
|
|
272
274
|
);
|
|
273
275
|
|
|
274
276
|
// eslint-disable-next-line prefer-const
|
|
@@ -281,7 +283,7 @@ export class Player {
|
|
|
281
283
|
|
|
282
284
|
this.hooks.expressionEvaluator.call(expressionEvaluator);
|
|
283
285
|
|
|
284
|
-
expressionEvaluator.hooks.onError.tap(
|
|
286
|
+
expressionEvaluator.hooks.onError.tap("player", (e) => {
|
|
285
287
|
flowResultDeferred.reject(e);
|
|
286
288
|
|
|
287
289
|
return true;
|
|
@@ -296,14 +298,14 @@ export class Player {
|
|
|
296
298
|
});
|
|
297
299
|
}
|
|
298
300
|
|
|
299
|
-
flowController.hooks.flow.tap(
|
|
300
|
-
flow.hooks.beforeTransition.tap(
|
|
301
|
+
flowController.hooks.flow.tap("player", (flow: FlowInstance) => {
|
|
302
|
+
flow.hooks.beforeTransition.tap("player", (state, transitionVal) => {
|
|
301
303
|
/** Checks to see if there are any transitions for a specific transition state (i.e. next, back). If not, it will default to * */
|
|
302
304
|
const computedTransitionVal = state.transitions[transitionVal]
|
|
303
305
|
? transitionVal
|
|
304
|
-
:
|
|
306
|
+
: "*";
|
|
305
307
|
if (state.onEnd && state.transitions[computedTransitionVal]) {
|
|
306
|
-
if (typeof state.onEnd ===
|
|
308
|
+
if (typeof state.onEnd === "object" && "exp" in state.onEnd) {
|
|
307
309
|
expressionEvaluator?.evaluate(state.onEnd.exp);
|
|
308
310
|
} else {
|
|
309
311
|
expressionEvaluator?.evaluate(state.onEnd as ExpressionType);
|
|
@@ -312,7 +314,7 @@ export class Player {
|
|
|
312
314
|
|
|
313
315
|
/** If the transition does not exist, then do not resolve any expressions */
|
|
314
316
|
if (
|
|
315
|
-
!(
|
|
317
|
+
!("transitions" in state) ||
|
|
316
318
|
!state.transitions[computedTransitionVal]
|
|
317
319
|
) {
|
|
318
320
|
return state;
|
|
@@ -321,15 +323,15 @@ export class Player {
|
|
|
321
323
|
/** resolves and sets the transition to the computed exp */
|
|
322
324
|
return setIn(
|
|
323
325
|
state,
|
|
324
|
-
[
|
|
325
|
-
resolveStrings(state.transitions[computedTransitionVal])
|
|
326
|
+
["transitions", computedTransitionVal],
|
|
327
|
+
resolveStrings(state.transitions[computedTransitionVal]),
|
|
326
328
|
) as any;
|
|
327
329
|
});
|
|
328
330
|
|
|
329
|
-
flow.hooks.skipTransition.tap(
|
|
330
|
-
if (currentState?.value.state_type ===
|
|
331
|
+
flow.hooks.skipTransition.tap("validation", (currentState) => {
|
|
332
|
+
if (currentState?.value.state_type === "VIEW") {
|
|
331
333
|
const { canTransition, validations } =
|
|
332
|
-
validationController.validateView(
|
|
334
|
+
validationController.validateView("navigation");
|
|
333
335
|
|
|
334
336
|
if (!canTransition && validations) {
|
|
335
337
|
const bindings = new Set(validations.keys());
|
|
@@ -342,36 +344,36 @@ export class Player {
|
|
|
342
344
|
return undefined;
|
|
343
345
|
});
|
|
344
346
|
|
|
345
|
-
flow.hooks.resolveTransitionNode.tap(
|
|
347
|
+
flow.hooks.resolveTransitionNode.tap("player", (state) => {
|
|
346
348
|
let newState = state;
|
|
347
349
|
|
|
348
|
-
if (
|
|
349
|
-
newState = setIn(state, [
|
|
350
|
+
if ("ref" in state) {
|
|
351
|
+
newState = setIn(state, ["ref"], resolveStrings(state.ref)) as any;
|
|
350
352
|
}
|
|
351
353
|
|
|
352
|
-
if (
|
|
354
|
+
if ("param" in state) {
|
|
353
355
|
newState = setIn(
|
|
354
356
|
state,
|
|
355
|
-
[
|
|
356
|
-
resolveStrings(state.param, false)
|
|
357
|
+
["param"],
|
|
358
|
+
resolveStrings(state.param, false),
|
|
357
359
|
) as any;
|
|
358
360
|
}
|
|
359
361
|
|
|
360
362
|
return newState;
|
|
361
363
|
});
|
|
362
364
|
|
|
363
|
-
flow.hooks.transition.tap(
|
|
364
|
-
if (newState.value.state_type !==
|
|
365
|
+
flow.hooks.transition.tap("player", (_oldState, newState) => {
|
|
366
|
+
if (newState.value.state_type !== "VIEW") {
|
|
365
367
|
validationController.reset();
|
|
366
368
|
}
|
|
367
369
|
});
|
|
368
370
|
|
|
369
|
-
flow.hooks.afterTransition.tap(
|
|
371
|
+
flow.hooks.afterTransition.tap("player", (flowInstance) => {
|
|
370
372
|
const value = flowInstance.currentState?.value;
|
|
371
|
-
if (value && value.state_type ===
|
|
373
|
+
if (value && value.state_type === "ACTION") {
|
|
372
374
|
const { exp } = value;
|
|
373
375
|
flowController?.transition(
|
|
374
|
-
String(expressionEvaluator?.evaluate(exp))
|
|
376
|
+
String(expressionEvaluator?.evaluate(exp)),
|
|
375
377
|
);
|
|
376
378
|
}
|
|
377
379
|
|
|
@@ -418,7 +420,7 @@ export class Player {
|
|
|
418
420
|
},
|
|
419
421
|
constants: this.constantsController,
|
|
420
422
|
});
|
|
421
|
-
viewController.hooks.view.tap(
|
|
423
|
+
viewController.hooks.view.tap("player", (view) => {
|
|
422
424
|
validationController.onView(view);
|
|
423
425
|
this.hooks.view.call(view);
|
|
424
426
|
});
|
|
@@ -445,7 +447,7 @@ export class Player {
|
|
|
445
447
|
.finally(() => this.hooks.onEnd.call());
|
|
446
448
|
},
|
|
447
449
|
state: {
|
|
448
|
-
status:
|
|
450
|
+
status: "in-progress",
|
|
449
451
|
flowResult: flowResultDeferred.promise,
|
|
450
452
|
controllers: {
|
|
451
453
|
data: dataController,
|
|
@@ -464,13 +466,13 @@ export class Player {
|
|
|
464
466
|
}
|
|
465
467
|
|
|
466
468
|
public async start(payload: FlowType): Promise<CompletedState> {
|
|
467
|
-
const ref = Symbol(payload?.id ??
|
|
469
|
+
const ref = Symbol(payload?.id ?? "payload");
|
|
468
470
|
|
|
469
471
|
/** A check to avoid updating the state for a flow that's not the current one */
|
|
470
472
|
const maybeUpdateState = <T extends PlayerFlowState>(newState: T) => {
|
|
471
473
|
if (this.state.ref !== ref) {
|
|
472
474
|
this.logger.warn(
|
|
473
|
-
`Received update for a flow that's not the current one
|
|
475
|
+
`Received update for a flow that's not the current one`,
|
|
474
476
|
);
|
|
475
477
|
|
|
476
478
|
return newState;
|
|
@@ -482,7 +484,7 @@ export class Player {
|
|
|
482
484
|
};
|
|
483
485
|
|
|
484
486
|
this.setState({
|
|
485
|
-
status:
|
|
487
|
+
status: "not-started",
|
|
486
488
|
ref,
|
|
487
489
|
});
|
|
488
490
|
|
|
@@ -499,7 +501,7 @@ export class Player {
|
|
|
499
501
|
// make sure to use the same ref as the starting one
|
|
500
502
|
const endProps = {
|
|
501
503
|
ref,
|
|
502
|
-
status:
|
|
504
|
+
status: "completed",
|
|
503
505
|
flow: state.flow,
|
|
504
506
|
controllers: {
|
|
505
507
|
data: state.controllers.data.makeReadOnly(),
|
|
@@ -512,7 +514,7 @@ export class Player {
|
|
|
512
514
|
});
|
|
513
515
|
} catch (error: any) {
|
|
514
516
|
const errorState: ErrorState = {
|
|
515
|
-
status:
|
|
517
|
+
status: "error",
|
|
516
518
|
ref,
|
|
517
519
|
flow: payload,
|
|
518
520
|
error,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ExpressionHandler, ExpressionType } from
|
|
2
|
-
import type { SchemaController } from
|
|
3
|
-
import type { Player, PlayerPlugin } from
|
|
1
|
+
import type { ExpressionHandler, ExpressionType } from "../expressions";
|
|
2
|
+
import type { SchemaController } from "../schema";
|
|
3
|
+
import type { Player, PlayerPlugin } from "../player";
|
|
4
4
|
|
|
5
5
|
/** Gets formatter for given formatName and formats value if found, returns value otherwise */
|
|
6
6
|
const createFormatFunction = (schema: SchemaController) => {
|
|
@@ -10,7 +10,7 @@ const createFormatFunction = (schema: SchemaController) => {
|
|
|
10
10
|
const handler: ExpressionHandler<[unknown, string], any> = (
|
|
11
11
|
ctx,
|
|
12
12
|
value,
|
|
13
|
-
formatName
|
|
13
|
+
formatName,
|
|
14
14
|
) => {
|
|
15
15
|
return (
|
|
16
16
|
schema.getFormatterForType({ type: formatName })?.format(value) ?? value
|
|
@@ -24,7 +24,7 @@ const createFormatFunction = (schema: SchemaController) => {
|
|
|
24
24
|
* A plugin that provides the out-of-the-box expressions for player
|
|
25
25
|
*/
|
|
26
26
|
export class DefaultExpPlugin implements PlayerPlugin {
|
|
27
|
-
name =
|
|
27
|
+
name = "flow-exp-plugin";
|
|
28
28
|
|
|
29
29
|
apply(player: Player) {
|
|
30
30
|
let formatFunction: ExpressionHandler<[unknown, string]> | undefined;
|
|
@@ -35,22 +35,22 @@ export class DefaultExpPlugin implements PlayerPlugin {
|
|
|
35
35
|
|
|
36
36
|
player.hooks.expressionEvaluator.tap(this.name, (expEvaluator) => {
|
|
37
37
|
if (formatFunction) {
|
|
38
|
-
expEvaluator.addExpressionFunction(
|
|
38
|
+
expEvaluator.addExpressionFunction("format", formatFunction);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
expEvaluator.addExpressionFunction(
|
|
41
|
+
expEvaluator.addExpressionFunction("log", (ctx, ...args) => {
|
|
42
42
|
player.logger.info(...args);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
expEvaluator.addExpressionFunction(
|
|
45
|
+
expEvaluator.addExpressionFunction("debug", (ctx, ...args) => {
|
|
46
46
|
player.logger.debug(...args);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
expEvaluator.addExpressionFunction(
|
|
50
|
-
|
|
50
|
+
"eval",
|
|
51
51
|
(ctx, ...args: [ExpressionType]) => {
|
|
52
52
|
return ctx.evaluate(...args);
|
|
53
|
-
}
|
|
53
|
+
},
|
|
54
54
|
);
|
|
55
55
|
});
|
|
56
56
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Player, PlayerPlugin } from "../player";
|
|
2
|
+
import {
|
|
3
|
+
ApplicabilityPlugin,
|
|
4
|
+
StringResolverPlugin,
|
|
5
|
+
SwitchPlugin,
|
|
6
|
+
TemplatePlugin,
|
|
7
|
+
toNodeResolveOptions,
|
|
8
|
+
} from "../view";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A plugin that provides the out-of-the-box expressions for player
|
|
12
|
+
*/
|
|
13
|
+
export class DefaultViewPlugin implements PlayerPlugin {
|
|
14
|
+
name = "default-view-plugin";
|
|
15
|
+
|
|
16
|
+
apply(player: Player) {
|
|
17
|
+
player.hooks.viewController.tap(this.name, (viewController) => {
|
|
18
|
+
viewController.hooks.view.tap(this.name, (view) => {
|
|
19
|
+
const pluginOptions = toNodeResolveOptions(view.resolverOptions);
|
|
20
|
+
new SwitchPlugin(pluginOptions).apply(view);
|
|
21
|
+
new ApplicabilityPlugin().apply(view);
|
|
22
|
+
new StringResolverPlugin().apply(view);
|
|
23
|
+
const templatePlugin = new TemplatePlugin(pluginOptions);
|
|
24
|
+
templatePlugin.apply(view);
|
|
25
|
+
view.hooks.onTemplatePluginCreated.call(templatePlugin);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -2,10 +2,10 @@ import type {
|
|
|
2
2
|
Expression,
|
|
3
3
|
ExpressionObject,
|
|
4
4
|
NavigationFlowState,
|
|
5
|
-
} from
|
|
6
|
-
import type { ExpressionEvaluator, ExpressionType } from
|
|
7
|
-
import type { FlowInstance } from
|
|
8
|
-
import type { Player, PlayerPlugin } from
|
|
5
|
+
} from "@player-ui/types";
|
|
6
|
+
import type { ExpressionEvaluator, ExpressionType } from "../expressions";
|
|
7
|
+
import type { FlowInstance } from "../controllers";
|
|
8
|
+
import type { Player, PlayerPlugin } from "../player";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A plugin that taps into the flow controller to evaluate available expressions
|
|
@@ -13,7 +13,7 @@ import type { Player, PlayerPlugin } from '../player';
|
|
|
13
13
|
* e.g: onStart, onEnd
|
|
14
14
|
*/
|
|
15
15
|
export class FlowExpPlugin implements PlayerPlugin {
|
|
16
|
-
name =
|
|
16
|
+
name = "flow-exp-plugin";
|
|
17
17
|
|
|
18
18
|
apply(player: Player) {
|
|
19
19
|
let expressionEvaluator: ExpressionEvaluator | undefined;
|
|
@@ -25,7 +25,7 @@ export class FlowExpPlugin implements PlayerPlugin {
|
|
|
25
25
|
*/
|
|
26
26
|
const handleEval = (exp: Expression | ExpressionObject) => {
|
|
27
27
|
if (exp) {
|
|
28
|
-
if (typeof exp ===
|
|
28
|
+
if (typeof exp === "object" && "exp" in exp) {
|
|
29
29
|
expressionEvaluator?.evaluate(exp.exp);
|
|
30
30
|
} else {
|
|
31
31
|
expressionEvaluator?.evaluate(exp as ExpressionType);
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
|
+
import { BindingParser } from "../../binding";
|
|
3
|
+
import { SchemaController } from "..";
|
|
4
|
+
|
|
5
|
+
const { parse } = new BindingParser({
|
|
6
|
+
get: () => undefined,
|
|
7
|
+
set: () => undefined,
|
|
8
|
+
evaluate: () => undefined,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe("schema", () => {
|
|
12
|
+
const schema = new SchemaController({
|
|
13
|
+
ROOT: {
|
|
14
|
+
pets: {
|
|
15
|
+
type: "PetType",
|
|
16
|
+
isArray: true,
|
|
17
|
+
},
|
|
18
|
+
owner: {
|
|
19
|
+
type: "OwnerType",
|
|
20
|
+
},
|
|
21
|
+
animals: {
|
|
22
|
+
type: "AnimalType",
|
|
23
|
+
isRecord: true,
|
|
24
|
+
},
|
|
25
|
+
automobile: {
|
|
26
|
+
type: "carType",
|
|
27
|
+
isArray: true,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
PetType: {
|
|
31
|
+
breed: {
|
|
32
|
+
type: "StringType",
|
|
33
|
+
},
|
|
34
|
+
name: {
|
|
35
|
+
type: "StringType",
|
|
36
|
+
validation: [
|
|
37
|
+
{
|
|
38
|
+
type: "required",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
age: {
|
|
43
|
+
type: "IntegerType",
|
|
44
|
+
validation: [
|
|
45
|
+
{
|
|
46
|
+
type: "required",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
OwnerType: {
|
|
52
|
+
name: {
|
|
53
|
+
type: "FirstNameType",
|
|
54
|
+
validation: [
|
|
55
|
+
{
|
|
56
|
+
type: "enum",
|
|
57
|
+
options: ["adam"],
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
AnimalType: {
|
|
63
|
+
age: {
|
|
64
|
+
type: "IntegerType",
|
|
65
|
+
validation: [
|
|
66
|
+
{
|
|
67
|
+
type: "required",
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
type: {
|
|
72
|
+
type: "StringType",
|
|
73
|
+
},
|
|
74
|
+
name: {
|
|
75
|
+
type: "StringType",
|
|
76
|
+
validation: [
|
|
77
|
+
{
|
|
78
|
+
type: "length",
|
|
79
|
+
min: 1,
|
|
80
|
+
max: 10,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
colors: {
|
|
85
|
+
type: "colorType",
|
|
86
|
+
isArray: true,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
carType: {
|
|
90
|
+
year: {
|
|
91
|
+
type: "IntegerType",
|
|
92
|
+
},
|
|
93
|
+
car: {
|
|
94
|
+
type: "makeType",
|
|
95
|
+
isRecord: true,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
colorType: {
|
|
99
|
+
color: {
|
|
100
|
+
type: "StringType",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
makeType: {
|
|
104
|
+
makeInteger: {
|
|
105
|
+
type: "IntegerType",
|
|
106
|
+
validation: [
|
|
107
|
+
{
|
|
108
|
+
type: "required",
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
model: {
|
|
113
|
+
type: "modelType",
|
|
114
|
+
isArray: true,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
modelType: {
|
|
118
|
+
color: {
|
|
119
|
+
type: "StringType",
|
|
120
|
+
},
|
|
121
|
+
body: {
|
|
122
|
+
type: "StringType",
|
|
123
|
+
validation: [
|
|
124
|
+
{
|
|
125
|
+
type: "required",
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("gets basic type info", () => {
|
|
133
|
+
expect(schema.getType(parse("owner.name"))?.type).toBe("FirstNameType");
|
|
134
|
+
expect(schema.getValidationsForBinding(parse("owner.name"))).toStrictEqual([
|
|
135
|
+
{
|
|
136
|
+
type: "enum",
|
|
137
|
+
options: ["adam"],
|
|
138
|
+
trigger: "change",
|
|
139
|
+
severity: "error",
|
|
140
|
+
},
|
|
141
|
+
]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("gets the type for objects in an array", () => {
|
|
145
|
+
expect(schema.getType(parse("pets.4.name"))?.type).toBe("StringType");
|
|
146
|
+
expect(
|
|
147
|
+
schema.getValidationsForBinding(parse("pets.999.name")),
|
|
148
|
+
).toStrictEqual([
|
|
149
|
+
{
|
|
150
|
+
type: "required",
|
|
151
|
+
trigger: "change",
|
|
152
|
+
severity: "error",
|
|
153
|
+
},
|
|
154
|
+
]);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("gets the type for an array parent", () => {
|
|
158
|
+
expect(schema.getType(parse("pets"))).toStrictEqual({
|
|
159
|
+
type: "PetType",
|
|
160
|
+
isArray: true,
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test("gets the type for an record parent", () => {
|
|
165
|
+
expect(schema.getType(parse("animals"))).toStrictEqual({
|
|
166
|
+
type: "AnimalType",
|
|
167
|
+
isRecord: true,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("gets the type for objects in a record", () => {
|
|
172
|
+
expect(schema.getType(parse("animals.cat.age"))?.type).toBe("IntegerType");
|
|
173
|
+
expect(
|
|
174
|
+
schema.getValidationsForBinding(parse("animals.cat.age")),
|
|
175
|
+
).toStrictEqual([
|
|
176
|
+
{
|
|
177
|
+
type: "required",
|
|
178
|
+
trigger: "change",
|
|
179
|
+
severity: "error",
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("gets the type for objects in a record in an array", () => {
|
|
185
|
+
expect(schema.getType(parse("animals.cat.colors.0.color"))?.type).toBe(
|
|
186
|
+
"StringType",
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test("gets the type for objects in a record with validation", () => {
|
|
191
|
+
expect(schema.getType(parse("animals.ginger.name"))?.type).toBe(
|
|
192
|
+
"StringType",
|
|
193
|
+
);
|
|
194
|
+
expect(
|
|
195
|
+
schema.getValidationsForBinding(parse("animals.ginger.name")),
|
|
196
|
+
).toStrictEqual([
|
|
197
|
+
{
|
|
198
|
+
type: "length",
|
|
199
|
+
min: 1,
|
|
200
|
+
max: 10,
|
|
201
|
+
trigger: "change",
|
|
202
|
+
severity: "error",
|
|
203
|
+
},
|
|
204
|
+
]);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test("gets the schema type for an array of objects in an object. and an array in an object of arrays", () => {
|
|
208
|
+
expect(schema.getType(parse("automobile.0.year"))?.type).toBe(
|
|
209
|
+
"IntegerType",
|
|
210
|
+
);
|
|
211
|
+
expect(
|
|
212
|
+
schema.getType(parse("automobile.0.car.honda.makeInteger"))?.type,
|
|
213
|
+
).toBe("IntegerType");
|
|
214
|
+
expect(
|
|
215
|
+
schema.getValidationsForBinding(
|
|
216
|
+
parse("automobile.0.car.honda.makeInteger"),
|
|
217
|
+
),
|
|
218
|
+
).toStrictEqual([
|
|
219
|
+
{
|
|
220
|
+
type: "required",
|
|
221
|
+
trigger: "change",
|
|
222
|
+
severity: "error",
|
|
223
|
+
},
|
|
224
|
+
]);
|
|
225
|
+
expect(
|
|
226
|
+
schema.getType(parse("automobile.0.car.honda.model.0.color"))?.type,
|
|
227
|
+
).toBe("StringType");
|
|
228
|
+
expect(
|
|
229
|
+
schema.getType(parse("automobile.0.car.honda.model.0.body"))?.type,
|
|
230
|
+
).toBe("StringType");
|
|
231
|
+
expect(
|
|
232
|
+
schema.getValidationsForBinding(
|
|
233
|
+
parse("automobile.0.car.honda.model.0.body"),
|
|
234
|
+
),
|
|
235
|
+
).toStrictEqual([
|
|
236
|
+
{
|
|
237
|
+
type: "required",
|
|
238
|
+
trigger: "change",
|
|
239
|
+
severity: "error",
|
|
240
|
+
},
|
|
241
|
+
]);
|
|
242
|
+
});
|
|
243
|
+
});
|
package/src/schema/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./schema";
|