@korajs/core 1.0.0-beta.4 → 1.0.0-beta.5

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 CHANGED
@@ -46,6 +46,7 @@ __export(index_exports, {
46
46
  StorageError: () => StorageError,
47
47
  SyncError: () => SyncError,
48
48
  advanceVector: () => advanceVector,
49
+ applyAtomicOp: () => applyAtomicOp,
49
50
  applyOperationTransforms: () => applyOperationTransforms,
50
51
  base64ToBytes: () => base64ToBytes,
51
52
  buildScopeMap: () => buildScopeMap,
@@ -95,6 +96,7 @@ __export(index_exports, {
95
96
  migrationStepsToSQL: () => migrationStepsToSQL,
96
97
  op: () => op,
97
98
  quoteIdent: () => quoteIdent,
99
+ replayOperationsForRecord: () => replayOperationsForRecord,
98
100
  resolveAtomicOp: () => resolveAtomicOp,
99
101
  revealSecret: () => revealSecret,
100
102
  rollbackStepsToSQL: () => rollbackStepsToSQL,
@@ -968,32 +970,36 @@ var KORA_ATOMIC_OP = /* @__PURE__ */ Symbol.for("kora.atomic_op");
968
970
  function isAtomicOp(value) {
969
971
  return typeof value === "object" && value !== null && KORA_ATOMIC_OP in value && value[KORA_ATOMIC_OP] === true;
970
972
  }
971
- function resolveAtomicOp(currentValue, sentinel) {
972
- switch (sentinel.type) {
973
+ function applyAtomicOp(currentValue, atomicOp) {
974
+ switch (atomicOp.type) {
973
975
  case "increment": {
974
976
  const current = typeof currentValue === "number" ? currentValue : 0;
975
- const operand = sentinel.value;
977
+ const operand = atomicOp.value;
976
978
  return current + operand;
977
979
  }
978
980
  case "max": {
979
981
  const current = typeof currentValue === "number" ? currentValue : Number.NEGATIVE_INFINITY;
980
- return Math.max(current, sentinel.value);
982
+ return Math.max(current, atomicOp.value);
981
983
  }
982
984
  case "min": {
983
985
  const current = typeof currentValue === "number" ? currentValue : Number.POSITIVE_INFINITY;
984
- return Math.min(current, sentinel.value);
986
+ return Math.min(current, atomicOp.value);
985
987
  }
986
988
  case "append": {
987
989
  const current = Array.isArray(currentValue) ? [...currentValue] : [];
988
- current.push(sentinel.value);
990
+ current.push(atomicOp.value);
989
991
  return current;
990
992
  }
991
993
  case "remove": {
992
994
  if (!Array.isArray(currentValue)) return [];
993
- return currentValue.filter((item) => item !== sentinel.value);
995
+ const target = JSON.stringify(atomicOp.value);
996
+ return currentValue.filter((item) => JSON.stringify(item) !== target);
994
997
  }
995
998
  }
996
999
  }
1000
+ function resolveAtomicOp(currentValue, sentinel) {
1001
+ return applyAtomicOp(currentValue, { type: sentinel.type, value: sentinel.value });
1002
+ }
997
1003
  function createSentinel(type, value) {
998
1004
  return Object.freeze({
999
1005
  [KORA_ATOMIC_OP]: true,
@@ -1061,6 +1067,46 @@ function toAtomicOp(sentinel) {
1061
1067
  return { type: sentinel.type, value: sentinel.value };
1062
1068
  }
1063
1069
 
1070
+ // src/operations/replay-record.ts
1071
+ function replayOperationsForRecord(ops) {
1072
+ let record = null;
1073
+ let deleted = false;
1074
+ const lastWriterKind = {};
1075
+ for (const op2 of ops) {
1076
+ switch (op2.type) {
1077
+ case "insert":
1078
+ if (op2.data) {
1079
+ record = { ...op2.data };
1080
+ deleted = false;
1081
+ for (const field of Object.keys(op2.data)) {
1082
+ lastWriterKind[field] = "lww";
1083
+ }
1084
+ }
1085
+ break;
1086
+ case "update":
1087
+ if (op2.data) {
1088
+ const next = { ...record ?? {} };
1089
+ for (const [field, value] of Object.entries(op2.data)) {
1090
+ const atomicOp = op2.atomicOps?.[field];
1091
+ if (atomicOp && lastWriterKind[field] === `atomic:${atomicOp.type}`) {
1092
+ next[field] = applyAtomicOp(next[field], atomicOp);
1093
+ } else {
1094
+ next[field] = value;
1095
+ }
1096
+ lastWriterKind[field] = atomicOp ? `atomic:${atomicOp.type}` : "lww";
1097
+ }
1098
+ record = next;
1099
+ deleted = false;
1100
+ }
1101
+ break;
1102
+ case "delete":
1103
+ deleted = true;
1104
+ break;
1105
+ }
1106
+ }
1107
+ return deleted ? null : record;
1108
+ }
1109
+
1064
1110
  // src/operations/op-data-binary.ts
1065
1111
  function isKoraBytesValue(value) {
1066
1112
  if (typeof value !== "object" || value === null) {
@@ -3283,6 +3329,7 @@ function generateProtoDefinitions(schema) {
3283
3329
  StorageError,
3284
3330
  SyncError,
3285
3331
  advanceVector,
3332
+ applyAtomicOp,
3286
3333
  applyOperationTransforms,
3287
3334
  base64ToBytes,
3288
3335
  buildScopeMap,
@@ -3332,6 +3379,7 @@ function generateProtoDefinitions(schema) {
3332
3379
  migrationStepsToSQL,
3333
3380
  op,
3334
3381
  quoteIdent,
3382
+ replayOperationsForRecord,
3335
3383
  resolveAtomicOp,
3336
3384
  revealSecret,
3337
3385
  rollbackStepsToSQL,