@routevn/creator-model 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/package.json +1 -1
  3. package/src/model.js +158 -1
package/README.md CHANGED
@@ -293,6 +293,7 @@ Currently implemented command types:
293
293
  - `layout.update`
294
294
  - `layout.delete`
295
295
  - `layout.move`
296
+ - `layout.schema.upgrade`
296
297
  - `character.sprite.create`
297
298
  - `character.sprite.update`
298
299
  - `character.sprite.delete`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@routevn/creator-model",
3
- "version": "1.4.1",
3
+ "version": "1.5.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/model.js CHANGED
@@ -40,7 +40,12 @@ const LINE_UPDATE_ACTIONS_PRESERVE_PATHS = ["dialogue.content"];
40
40
  const LINE_UPDATE_ACTIONS_PRESERVE_PATHS_SET = new Set(
41
41
  LINE_UPDATE_ACTIONS_PRESERVE_PATHS,
42
42
  );
43
+ const CURRENT_LAYOUT_SCHEMA_VERSION = 2;
43
44
  const isPositiveFiniteNumber = (value) => isFiniteNumber(value) && value > 0;
45
+ const normalizeLayoutSchemaVersion = (value) =>
46
+ Number.isInteger(value) && value >= 1 ? value : 1;
47
+ const isSupportedLayoutSchemaVersion = (value) =>
48
+ value === CURRENT_LAYOUT_SCHEMA_VERSION;
44
49
  const createEmptyCollectionState = () => ({
45
50
  items: {},
46
51
  tree: [],
@@ -376,7 +381,7 @@ const LAYOUT_ELEMENT_BASE_TYPES = [
376
381
  "container-ref-confirm-dialog-ok",
377
382
  "container-ref-confirm-dialog-cancel",
378
383
  ];
379
- export const SCHEMA_VERSION = 4;
384
+ export const SCHEMA_VERSION = 5;
380
385
  const LAYOUT_CONTAINER_ELEMENT_TYPES = [
381
386
  "folder",
382
387
  "container",
@@ -3392,6 +3397,8 @@ const validateLayoutElementData = ({
3392
3397
  "hover",
3393
3398
  "click",
3394
3399
  "rightClick",
3400
+ "scrollUp",
3401
+ "scrollDown",
3395
3402
  "anchorToBottom",
3396
3403
  "thumbImageId",
3397
3404
  "barImageId",
@@ -3841,6 +3848,32 @@ const validateLayoutElementData = ({
3841
3848
  }
3842
3849
  }
3843
3850
 
3851
+ if (data.scrollUp !== undefined) {
3852
+ {
3853
+ const result = validateLayoutElementInteraction({
3854
+ interaction: data.scrollUp,
3855
+ path: `${path}.scrollUp`,
3856
+ errorFactory,
3857
+ });
3858
+ if (result?.valid === false) {
3859
+ return result;
3860
+ }
3861
+ }
3862
+ }
3863
+
3864
+ if (data.scrollDown !== undefined) {
3865
+ {
3866
+ const result = validateLayoutElementInteraction({
3867
+ interaction: data.scrollDown,
3868
+ path: `${path}.scrollDown`,
3869
+ errorFactory,
3870
+ });
3871
+ if (result?.valid === false) {
3872
+ return result;
3873
+ }
3874
+ }
3875
+ }
3876
+
3844
3877
  if (
3845
3878
  data.anchorToBottom !== undefined &&
3846
3879
  typeof data.anchorToBottom !== "boolean"
@@ -3940,6 +3973,8 @@ const validateLayoutElementItems = ({ items, path, errorFactory }) => {
3940
3973
  "hover",
3941
3974
  "click",
3942
3975
  "rightClick",
3976
+ "scrollUp",
3977
+ "scrollDown",
3943
3978
  "anchorToBottom",
3944
3979
  "thumbImageId",
3945
3980
  "barImageId",
@@ -4967,6 +5002,7 @@ const validateLayoutItems = ({ items, path, errorFactory }) => {
4967
5002
  "description",
4968
5003
  "tagIds",
4969
5004
  "layoutType",
5005
+ "layoutSchemaVersion",
4970
5006
  "isFragment",
4971
5007
  "thumbnailFileId",
4972
5008
  "preview",
@@ -5049,6 +5085,16 @@ const validateLayoutItems = ({ items, path, errorFactory }) => {
5049
5085
  );
5050
5086
  }
5051
5087
 
5088
+ if (
5089
+ item.layoutSchemaVersion !== undefined &&
5090
+ !isSupportedLayoutSchemaVersion(item.layoutSchemaVersion)
5091
+ ) {
5092
+ return invalidFromErrorFactory(
5093
+ errorFactory,
5094
+ `${itemPath}.layoutSchemaVersion must be ${CURRENT_LAYOUT_SCHEMA_VERSION} when provided`,
5095
+ );
5096
+ }
5097
+
5052
5098
  if (
5053
5099
  item.isFragment !== undefined &&
5054
5100
  typeof item.isFragment !== "boolean"
@@ -10490,6 +10536,7 @@ const validateLayoutCreateData = ({ data, errorFactory }) => {
10490
10536
  "description",
10491
10537
  "tagIds",
10492
10538
  "layoutType",
10539
+ "layoutSchemaVersion",
10493
10540
  "isFragment",
10494
10541
  "thumbnailFileId",
10495
10542
  "preview",
@@ -10557,6 +10604,16 @@ const validateLayoutCreateData = ({ data, errorFactory }) => {
10557
10604
  );
10558
10605
  }
10559
10606
 
10607
+ if (
10608
+ data.layoutSchemaVersion !== undefined &&
10609
+ !isSupportedLayoutSchemaVersion(data.layoutSchemaVersion)
10610
+ ) {
10611
+ return invalidFromErrorFactory(
10612
+ errorFactory,
10613
+ `payload.data.layoutSchemaVersion must be ${CURRENT_LAYOUT_SCHEMA_VERSION} when provided`,
10614
+ );
10615
+ }
10616
+
10560
10617
  if (data.isFragment !== undefined && typeof data.isFragment !== "boolean") {
10561
10618
  return invalidFromErrorFactory(
10562
10619
  errorFactory,
@@ -11363,6 +11420,32 @@ const createEmptyNestedCollection = () => ({
11363
11420
  tree: [],
11364
11421
  });
11365
11422
 
11423
+ const isDirectedLayoutContainer = (item) =>
11424
+ item?.direction === "horizontal" || item?.direction === "vertical";
11425
+
11426
+ const upgradeLayoutTreeOrder = ({ nodes, items, parentItem } = {}) => {
11427
+ const sourceNodes = Array.isArray(nodes) ? nodes : [];
11428
+ const orderedNodes = isDirectedLayoutContainer(parentItem)
11429
+ ? sourceNodes
11430
+ : [...sourceNodes].reverse();
11431
+
11432
+ return orderedNodes.map((node) => {
11433
+ const nextNode = {
11434
+ ...node,
11435
+ };
11436
+
11437
+ if (Array.isArray(node?.children) && node.children.length > 0) {
11438
+ nextNode.children = upgradeLayoutTreeOrder({
11439
+ nodes: node.children,
11440
+ items,
11441
+ parentItem: items?.[node.id],
11442
+ });
11443
+ }
11444
+
11445
+ return nextNode;
11446
+ });
11447
+ };
11448
+
11366
11449
  const findSectionLocation = ({ state, sectionId }) => {
11367
11450
  for (const [sceneId, scene] of Object.entries(state.scenes.items)) {
11368
11451
  if (scene?.type !== "scene") {
@@ -16836,6 +16919,11 @@ const COMMAND_DEFINITIONS = [
16836
16919
  }
16837
16920
  : {}),
16838
16921
  layoutType: payload.data.layoutType,
16922
+ ...(payload.data.layoutSchemaVersion !== undefined
16923
+ ? {
16924
+ layoutSchemaVersion: payload.data.layoutSchemaVersion,
16925
+ }
16926
+ : {}),
16839
16927
  isFragment: payload.data.isFragment,
16840
16928
  ...(payload.data.thumbnailFileId !== undefined
16841
16929
  ? {
@@ -16924,6 +17012,75 @@ const COMMAND_DEFINITIONS = [
16924
17012
  }
16925
17013
  },
16926
17014
  }),
17015
+ {
17016
+ type: "layout.schema.upgrade",
17017
+ validatePayload: ({ payload }) => {
17018
+ {
17019
+ const result = validateExactKeys({
17020
+ value: payload,
17021
+ expectedKeys: ["layoutIds", "targetSchemaVersion"],
17022
+ path: "payload",
17023
+ errorFactory: createPayloadValidationError,
17024
+ });
17025
+ if (result?.valid === false) {
17026
+ return result;
17027
+ }
17028
+ }
17029
+
17030
+ {
17031
+ const result = validateRequiredUniqueIdArray({
17032
+ value: payload.layoutIds,
17033
+ path: "payload.layoutIds",
17034
+ errorFactory: createPayloadValidationError,
17035
+ });
17036
+ if (result?.valid === false) {
17037
+ return result;
17038
+ }
17039
+ }
17040
+
17041
+ if (payload.targetSchemaVersion !== CURRENT_LAYOUT_SCHEMA_VERSION) {
17042
+ return invalidPayload(
17043
+ `payload.targetSchemaVersion must be ${CURRENT_LAYOUT_SCHEMA_VERSION}`,
17044
+ );
17045
+ }
17046
+
17047
+ return VALID_RESULT;
17048
+ },
17049
+ validateAgainstState: ({ state, payload }) => {
17050
+ for (const layoutId of payload.layoutIds) {
17051
+ const layout = state.layouts.items[layoutId];
17052
+ if (!isPlainObject(layout) || layout.type !== "layout") {
17053
+ return invalidPrecondition(
17054
+ "payload.layoutIds must reference existing layouts",
17055
+ {
17056
+ layoutId,
17057
+ },
17058
+ );
17059
+ }
17060
+ }
17061
+
17062
+ return VALID_RESULT;
17063
+ },
17064
+ reduce: ({ state, payload }) => {
17065
+ for (const layoutId of payload.layoutIds) {
17066
+ const layout = state.layouts.items[layoutId];
17067
+ if (
17068
+ normalizeLayoutSchemaVersion(layout.layoutSchemaVersion) >=
17069
+ payload.targetSchemaVersion
17070
+ ) {
17071
+ continue;
17072
+ }
17073
+
17074
+ layout.elements.tree = upgradeLayoutTreeOrder({
17075
+ nodes: layout.elements.tree,
17076
+ items: layout.elements.items,
17077
+ });
17078
+ layout.layoutSchemaVersion = payload.targetSchemaVersion;
17079
+ }
17080
+
17081
+ return state;
17082
+ },
17083
+ },
16927
17084
  ...createFolderedCollectionCommandDefinitions({
16928
17085
  familyName: "control",
16929
17086
  collectionKey: "controls",