@routevn/creator-model 1.2.9 → 1.2.10

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/model.js +109 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@routevn/creator-model",
3
- "version": "1.2.9",
3
+ "version": "1.2.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/model.js CHANGED
@@ -36,6 +36,10 @@ const COLLECTION_KEYS = [
36
36
  "controls",
37
37
  ];
38
38
  const ROOT_KEYS = ["project", "story", ...COLLECTION_KEYS];
39
+ const LINE_UPDATE_ACTIONS_PRESERVE_PATHS = ["dialogue.content"];
40
+ const LINE_UPDATE_ACTIONS_PRESERVE_PATHS_SET = new Set(
41
+ LINE_UPDATE_ACTIONS_PRESERVE_PATHS,
42
+ );
39
43
  const createEmptyCollectionState = () => ({
40
44
  items: {},
41
45
  tree: [],
@@ -5834,6 +5838,91 @@ const validateLineUpdateActionsData = ({ data, errorFactory }) => {
5834
5838
  }
5835
5839
  };
5836
5840
 
5841
+ const validateLineUpdateActionsPreserve = ({
5842
+ preserve,
5843
+ data,
5844
+ replace,
5845
+ errorFactory,
5846
+ }) => {
5847
+ if (preserve === undefined) {
5848
+ return VALID_RESULT;
5849
+ }
5850
+
5851
+ if (replace === true) {
5852
+ return invalidFromErrorFactory(
5853
+ errorFactory,
5854
+ "payload.preserve is only supported when payload.replace is not true",
5855
+ );
5856
+ }
5857
+
5858
+ if (!Array.isArray(preserve)) {
5859
+ return invalidFromErrorFactory(
5860
+ errorFactory,
5861
+ "payload.preserve must be an array when provided",
5862
+ );
5863
+ }
5864
+
5865
+ const seen = new Set();
5866
+ for (let index = 0; index < preserve.length; index += 1) {
5867
+ const path = preserve[index];
5868
+ const preservePath = `payload.preserve[${index}]`;
5869
+
5870
+ if (!isNonEmptyString(path)) {
5871
+ return invalidFromErrorFactory(
5872
+ errorFactory,
5873
+ `${preservePath} must be a non-empty string`,
5874
+ );
5875
+ }
5876
+
5877
+ if (!LINE_UPDATE_ACTIONS_PRESERVE_PATHS_SET.has(path)) {
5878
+ return invalidFromErrorFactory(
5879
+ errorFactory,
5880
+ `${preservePath} must be one of: ${LINE_UPDATE_ACTIONS_PRESERVE_PATHS.join(", ")}`,
5881
+ );
5882
+ }
5883
+
5884
+ if (seen.has(path)) {
5885
+ return invalidFromErrorFactory(
5886
+ errorFactory,
5887
+ `${preservePath} must not duplicate another preserve path`,
5888
+ );
5889
+ }
5890
+ seen.add(path);
5891
+
5892
+ if (path === "dialogue.content" && !isPlainObject(data?.dialogue)) {
5893
+ return invalidFromErrorFactory(
5894
+ errorFactory,
5895
+ "payload.data.dialogue must be an object when preserving dialogue.content",
5896
+ );
5897
+ }
5898
+ }
5899
+
5900
+ return VALID_RESULT;
5901
+ };
5902
+
5903
+ const applyLineUpdateActionsPreserve = ({ currentActions, data, preserve }) => {
5904
+ const nextData = structuredClone(data || {});
5905
+ if (!Array.isArray(preserve) || preserve.length === 0) {
5906
+ return nextData;
5907
+ }
5908
+
5909
+ if (
5910
+ preserve.includes("dialogue.content") &&
5911
+ isPlainObject(nextData.dialogue) &&
5912
+ !Object.hasOwn(nextData.dialogue, "content")
5913
+ ) {
5914
+ const currentContent = currentActions?.dialogue?.content;
5915
+ if (currentContent !== undefined) {
5916
+ nextData.dialogue = {
5917
+ ...structuredClone(nextData.dialogue),
5918
+ content: structuredClone(currentContent),
5919
+ };
5920
+ }
5921
+ }
5922
+
5923
+ return nextData;
5924
+ };
5925
+
5837
5926
  const validateImageCreateData = ({ data, errorFactory }) => {
5838
5927
  if (!isPlainObject(data)) {
5839
5928
  return invalidFromErrorFactory(
@@ -10445,7 +10534,7 @@ const COMMAND_DEFINITIONS = [
10445
10534
  {
10446
10535
  const result = validateAllowedKeys({
10447
10536
  value: payload,
10448
- allowedKeys: ["lineId", "data", "replace"],
10537
+ allowedKeys: ["lineId", "data", "replace", "preserve"],
10449
10538
  path: "payload",
10450
10539
  errorFactory: createPayloadValidationError,
10451
10540
  });
@@ -10476,6 +10565,18 @@ const COMMAND_DEFINITIONS = [
10476
10565
  "payload.replace must be a boolean when provided",
10477
10566
  );
10478
10567
  }
10568
+
10569
+ {
10570
+ const result = validateLineUpdateActionsPreserve({
10571
+ preserve: payload.preserve,
10572
+ data: payload.data,
10573
+ replace: payload.replace,
10574
+ errorFactory: createPayloadValidationError,
10575
+ });
10576
+ if (result?.valid === false) {
10577
+ return result;
10578
+ }
10579
+ }
10479
10580
  },
10480
10581
  validateAgainstState: ({ state, payload }) => {
10481
10582
  if (!findLineLocation({ state, lineId: payload.lineId })) {
@@ -10487,12 +10588,17 @@ const COMMAND_DEFINITIONS = [
10487
10588
  reduce: ({ state, payload }) => {
10488
10589
  const location = findLineLocation({ state, lineId: payload.lineId });
10489
10590
  const line = location.line;
10591
+ const nextData = applyLineUpdateActionsPreserve({
10592
+ currentActions: line.actions,
10593
+ data: payload.data,
10594
+ preserve: payload.preserve,
10595
+ });
10490
10596
  line.actions =
10491
10597
  payload.replace === true
10492
- ? structuredClone(payload.data)
10598
+ ? structuredClone(nextData)
10493
10599
  : {
10494
10600
  ...structuredClone(line.actions),
10495
- ...structuredClone(payload.data),
10601
+ ...structuredClone(nextData),
10496
10602
  };
10497
10603
  return state;
10498
10604
  },