document-model 1.4.0 → 1.6.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.
Files changed (47) hide show
  1. package/dist/browser/cjs/document-model.js +2 -2
  2. package/dist/browser/cjs/document.js +2 -2
  3. package/dist/browser/cjs/index.js +2 -2
  4. package/dist/{node/cjs/internal/index-DxD7Ha1j.js → browser/cjs/internal/index-BImZF-Wk.js} +2 -2
  5. package/dist/browser/cjs/internal/index-BImZF-Wk.js.map +1 -0
  6. package/dist/browser/cjs/internal/{index-DdOJi6Ua.js → index-vlbA6Asd.js} +2 -2
  7. package/dist/browser/cjs/internal/{index-DdOJi6Ua.js.map → index-vlbA6Asd.js.map} +1 -1
  8. package/dist/browser/cjs/internal/{object-CRlmL8Nt.js → object-9Wvjprnm.js} +151 -124
  9. package/dist/browser/cjs/internal/object-9Wvjprnm.js.map +1 -0
  10. package/dist/browser/es/document-model.js +2 -2
  11. package/dist/browser/es/document.js +2 -2
  12. package/dist/browser/es/index.js +2 -2
  13. package/dist/browser/es/internal/{index-C1HKYMZA.js → index-CuhiYn-8.js} +2 -2
  14. package/dist/browser/es/internal/{index-C1HKYMZA.js.map → index-CuhiYn-8.js.map} +1 -1
  15. package/dist/browser/es/internal/{index-BsGRYydP.js → index-Drp90r05.js} +2 -2
  16. package/dist/browser/es/internal/index-Drp90r05.js.map +1 -0
  17. package/dist/browser/es/internal/{object-B562qKhQ.js → object-CyAog_F_.js} +151 -124
  18. package/dist/browser/es/internal/object-CyAog_F_.js.map +1 -0
  19. package/dist/browser/src/document/utils/document-helpers.d.ts +1 -0
  20. package/dist/node/cjs/document-model.js +2 -2
  21. package/dist/node/cjs/document.js +2 -2
  22. package/dist/node/cjs/index.js +2 -2
  23. package/dist/{browser/cjs/internal/index-pAtJQrtD.js → node/cjs/internal/index-CJIU8iX-.js} +2 -2
  24. package/dist/node/cjs/internal/index-CJIU8iX-.js.map +1 -0
  25. package/dist/node/cjs/internal/{index-BWc0K1Dk.js → index-DWeC8dwW.js} +2 -2
  26. package/dist/node/cjs/internal/{index-BWc0K1Dk.js.map → index-DWeC8dwW.js.map} +1 -1
  27. package/dist/node/cjs/internal/{object-_zq9luMS.js → object-op6YzhH1.js} +152 -125
  28. package/dist/node/cjs/internal/object-op6YzhH1.js.map +1 -0
  29. package/dist/node/es/document-model.js +2 -2
  30. package/dist/node/es/document.js +2 -2
  31. package/dist/node/es/index.js +2 -2
  32. package/dist/node/es/internal/{index-D8WTToX1.js → index-BNAE-_Hg.js} +2 -2
  33. package/dist/node/es/internal/{index-D8WTToX1.js.map → index-BNAE-_Hg.js.map} +1 -1
  34. package/dist/node/es/internal/{index-DkkBVgni.js → index-B_7z_4EV.js} +2 -2
  35. package/dist/node/es/internal/index-B_7z_4EV.js.map +1 -0
  36. package/dist/node/es/internal/{object-D3jjs7tr.js → object-BuK9PFjs.js} +152 -125
  37. package/dist/node/es/internal/object-BuK9PFjs.js.map +1 -0
  38. package/dist/node/src/document/utils/document-helpers.d.ts +1 -0
  39. package/package.json +1 -1
  40. package/dist/browser/cjs/internal/index-pAtJQrtD.js.map +0 -1
  41. package/dist/browser/cjs/internal/object-CRlmL8Nt.js.map +0 -1
  42. package/dist/browser/es/internal/index-BsGRYydP.js.map +0 -1
  43. package/dist/browser/es/internal/object-B562qKhQ.js.map +0 -1
  44. package/dist/node/cjs/internal/index-DxD7Ha1j.js.map +0 -1
  45. package/dist/node/cjs/internal/object-_zq9luMS.js.map +0 -1
  46. package/dist/node/es/internal/index-DkkBVgni.js.map +0 -1
  47. package/dist/node/es/internal/object-D3jjs7tr.js.map +0 -1
@@ -1061,8 +1061,10 @@ function validateOperations(operations) {
1061
1061
  const scopes = Object.keys(operations);
1062
1062
  for (const scope of scopes) {
1063
1063
  const ops = operations[scope].sort((a, b) => a.index - b.index);
1064
+ let opIndex = -1;
1064
1065
  for (let i = 0; i < ops.length; i++) {
1065
- if (ops[i].index !== i) {
1066
+ opIndex = opIndex + 1 + ops[i].skip;
1067
+ if (ops[i].index !== opIndex) {
1066
1068
  errors.push({
1067
1069
  message: `Invalid operation index ${ops[i].index} at position ${i}`,
1068
1070
  details: {
@@ -1076,129 +1078,6 @@ function validateOperations(operations) {
1076
1078
  }
1077
1079
  return errors;
1078
1080
  }
1079
- const createZip = async (document) => {
1080
- const zip = new JSZip();
1081
- const { name, revision, documentType, created, lastModified } = document;
1082
- const header = {
1083
- name,
1084
- revision,
1085
- documentType,
1086
- created,
1087
- lastModified
1088
- };
1089
- zip.file("header.json", JSON.stringify(header, null, 2));
1090
- zip.file(
1091
- "state.json",
1092
- JSON.stringify(document.initialState || {}, null, 2)
1093
- );
1094
- zip.file("operations.json", JSON.stringify(document.operations, null, 2));
1095
- if (document.attachments) {
1096
- const attachments = Object.keys(document.attachments);
1097
- attachments.forEach((key) => {
1098
- const { data, ...attributes } = document.attachments[key];
1099
- zip.file(key, data, {
1100
- base64: true,
1101
- createFolders: true,
1102
- comment: JSON.stringify(attributes)
1103
- });
1104
- });
1105
- }
1106
- return zip;
1107
- };
1108
- const saveToFile = async (document, path2, extension, name) => {
1109
- const zip = await createZip(document);
1110
- const file = await zip.generateAsync({
1111
- type: "uint8array",
1112
- streamFiles: true
1113
- });
1114
- const fileName = name ?? document.name;
1115
- const fileExtension = `.${extension}.zip`;
1116
- return writeFile(
1117
- path2,
1118
- fileName.endsWith(fileExtension) ? fileName : `${fileName}${fileExtension}`,
1119
- file
1120
- );
1121
- };
1122
- const saveToFileHandle = async (document, input) => {
1123
- const zip = await createZip(document);
1124
- const blob = await zip.generateAsync({ type: "blob" });
1125
- const writable = await input.createWritable();
1126
- await writable.write(blob);
1127
- await writable.close();
1128
- };
1129
- const loadFromFile = async (path2, reducer, options) => {
1130
- const file = readFile(path2);
1131
- return loadFromInput(file, reducer, options);
1132
- };
1133
- const loadFromInput = async (input, reducer, options) => {
1134
- const zip = new JSZip();
1135
- await zip.loadAsync(input);
1136
- return loadFromZip(zip, reducer, options);
1137
- };
1138
- async function loadFromZip(zip, reducer, options) {
1139
- const initialStateZip = zip.file("state.json");
1140
- if (!initialStateZip) {
1141
- throw new Error("Initial state not found");
1142
- }
1143
- const initialStateStr = await initialStateZip.async("string");
1144
- const initialState = JSON.parse(initialStateStr);
1145
- const headerZip = zip.file("header.json");
1146
- let header = void 0;
1147
- if (headerZip) {
1148
- header = JSON.parse(await headerZip.async("string"));
1149
- }
1150
- const operationsZip = zip.file("operations.json");
1151
- if (!operationsZip) {
1152
- throw new Error("Operations history not found");
1153
- }
1154
- const operations = JSON.parse(
1155
- await operationsZip.async("string")
1156
- );
1157
- const operationsError = validateOperations(operations);
1158
- if (operationsError.length) {
1159
- const errorMessages = operationsError.map((err) => err.message);
1160
- throw new Error(errorMessages.join("\n"));
1161
- }
1162
- let result = replayDocument(
1163
- initialState,
1164
- operations,
1165
- reducer,
1166
- void 0,
1167
- header,
1168
- {},
1169
- options
1170
- );
1171
- if (header) {
1172
- result = {
1173
- ...result,
1174
- ...header
1175
- };
1176
- }
1177
- return result;
1178
- }
1179
- function getFileAttributes(file) {
1180
- const extension = file.replace(/^.*\./, "") || void 0;
1181
- const fileName = file.replace(/^.*[/\\]/, "") || void 0;
1182
- return { extension, fileName };
1183
- }
1184
- async function getRemoteFile(url) {
1185
- const { buffer, mimeType = "application/octet-stream" } = await fetchFile(url);
1186
- const attributes = getFileAttributes(url);
1187
- const data = buffer.toString("base64");
1188
- return {
1189
- data,
1190
- hash: hash(data),
1191
- mimeType,
1192
- ...attributes
1193
- };
1194
- }
1195
- async function getLocalFile(path2) {
1196
- const buffer = await getFile(path2);
1197
- const mimeType = mime.getType(path2) || "application/octet-stream";
1198
- const attributes = getFileAttributes(path2);
1199
- const data = buffer.toString("base64");
1200
- return { data, hash: hash(data), mimeType, ...attributes };
1201
- }
1202
1081
  var IntegrityIssueType = /* @__PURE__ */ ((IntegrityIssueType2) => {
1203
1082
  IntegrityIssueType2["UNEXPECTED_INDEX"] = "UNEXPECTED_INDEX";
1204
1083
  return IntegrityIssueType2;
@@ -1510,6 +1389,22 @@ function filterDuplicatedOperations(targetOperations, sourceOperations) {
1510
1389
  return true;
1511
1390
  });
1512
1391
  }
1392
+ function filterDocumentOperationsResultingState(documentOperations) {
1393
+ if (!documentOperations) {
1394
+ return {};
1395
+ }
1396
+ const entries = Object.entries(documentOperations);
1397
+ return entries.reduce(
1398
+ (acc, [scope, operations]) => ({
1399
+ ...acc,
1400
+ [scope]: operations.map((op) => {
1401
+ const { resultingState, ...restProps } = op;
1402
+ return restProps;
1403
+ })
1404
+ }),
1405
+ {}
1406
+ );
1407
+ }
1513
1408
  const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1514
1409
  __proto__: null,
1515
1410
  IntegrityIssueSubType,
@@ -1518,6 +1413,7 @@ const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
1518
1413
  attachBranch,
1519
1414
  checkCleanedOperationsIntegrity,
1520
1415
  checkOperationsIntegrity,
1416
+ filterDocumentOperationsResultingState,
1521
1417
  filterDuplicatedOperations,
1522
1418
  garbageCollect,
1523
1419
  garbageCollectDocumentOperations,
@@ -1534,6 +1430,137 @@ const documentHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
1534
1430
  sortOperations: sortOperations$1,
1535
1431
  split
1536
1432
  }, Symbol.toStringTag, { value: "Module" }));
1433
+ const createZip = async (document) => {
1434
+ const zip = new JSZip();
1435
+ const { name, revision, documentType, created, lastModified } = document;
1436
+ const header = {
1437
+ name,
1438
+ revision,
1439
+ documentType,
1440
+ created,
1441
+ lastModified
1442
+ };
1443
+ zip.file("header.json", JSON.stringify(header, null, 2));
1444
+ zip.file(
1445
+ "state.json",
1446
+ JSON.stringify(document.initialState || {}, null, 2)
1447
+ );
1448
+ zip.file(
1449
+ "operations.json",
1450
+ JSON.stringify(
1451
+ filterDocumentOperationsResultingState(document.operations),
1452
+ null,
1453
+ 2
1454
+ )
1455
+ );
1456
+ if (document.attachments) {
1457
+ const attachments = Object.keys(document.attachments);
1458
+ attachments.forEach((key) => {
1459
+ const { data, ...attributes } = document.attachments[key];
1460
+ zip.file(key, data, {
1461
+ base64: true,
1462
+ createFolders: true,
1463
+ comment: JSON.stringify(attributes)
1464
+ });
1465
+ });
1466
+ }
1467
+ return zip;
1468
+ };
1469
+ const saveToFile = async (document, path2, extension, name) => {
1470
+ const zip = await createZip(document);
1471
+ const file = await zip.generateAsync({
1472
+ type: "uint8array",
1473
+ streamFiles: true
1474
+ });
1475
+ const fileName = name ?? document.name;
1476
+ const fileExtension = `.${extension}.zip`;
1477
+ return writeFile(
1478
+ path2,
1479
+ fileName.endsWith(fileExtension) ? fileName : `${fileName}${fileExtension}`,
1480
+ file
1481
+ );
1482
+ };
1483
+ const saveToFileHandle = async (document, input) => {
1484
+ const zip = await createZip(document);
1485
+ const blob = await zip.generateAsync({ type: "blob" });
1486
+ const writable = await input.createWritable();
1487
+ await writable.write(blob);
1488
+ await writable.close();
1489
+ };
1490
+ const loadFromFile = async (path2, reducer, options) => {
1491
+ const file = readFile(path2);
1492
+ return loadFromInput(file, reducer, options);
1493
+ };
1494
+ const loadFromInput = async (input, reducer, options) => {
1495
+ const zip = new JSZip();
1496
+ await zip.loadAsync(input);
1497
+ return loadFromZip(zip, reducer, options);
1498
+ };
1499
+ async function loadFromZip(zip, reducer, options) {
1500
+ const initialStateZip = zip.file("state.json");
1501
+ if (!initialStateZip) {
1502
+ throw new Error("Initial state not found");
1503
+ }
1504
+ const initialStateStr = await initialStateZip.async("string");
1505
+ const initialState = JSON.parse(initialStateStr);
1506
+ const headerZip = zip.file("header.json");
1507
+ let header = void 0;
1508
+ if (headerZip) {
1509
+ header = JSON.parse(await headerZip.async("string"));
1510
+ }
1511
+ const operationsZip = zip.file("operations.json");
1512
+ if (!operationsZip) {
1513
+ throw new Error("Operations history not found");
1514
+ }
1515
+ const operations = JSON.parse(
1516
+ await operationsZip.async("string")
1517
+ );
1518
+ const clearedOperations = garbageCollectDocumentOperations(operations);
1519
+ const operationsError = validateOperations(clearedOperations);
1520
+ if (operationsError.length) {
1521
+ const errorMessages = operationsError.map((err) => err.message);
1522
+ throw new Error(errorMessages.join("\n"));
1523
+ }
1524
+ let result = replayDocument(
1525
+ initialState,
1526
+ clearedOperations,
1527
+ reducer,
1528
+ void 0,
1529
+ header,
1530
+ {},
1531
+ options
1532
+ );
1533
+ if (header) {
1534
+ result = {
1535
+ ...result,
1536
+ ...header
1537
+ };
1538
+ }
1539
+ return result;
1540
+ }
1541
+ function getFileAttributes(file) {
1542
+ const extension = file.replace(/^.*\./, "") || void 0;
1543
+ const fileName = file.replace(/^.*[/\\]/, "") || void 0;
1544
+ return { extension, fileName };
1545
+ }
1546
+ async function getRemoteFile(url) {
1547
+ const { buffer, mimeType = "application/octet-stream" } = await fetchFile(url);
1548
+ const attributes = getFileAttributes(url);
1549
+ const data = buffer.toString("base64");
1550
+ return {
1551
+ data,
1552
+ hash: hash(data),
1553
+ mimeType,
1554
+ ...attributes
1555
+ };
1556
+ }
1557
+ async function getLocalFile(path2) {
1558
+ const buffer = await getFile(path2);
1559
+ const mimeType = mime.getType(path2) || "application/octet-stream";
1560
+ const attributes = getFileAttributes(path2);
1561
+ const data = buffer.toString("base64");
1562
+ return { data, hash: hash(data), mimeType, ...attributes };
1563
+ }
1537
1564
  function getNextRevision(document, action) {
1538
1565
  let latestOperation;
1539
1566
  if ("index" in action) {
@@ -2332,4 +2359,4 @@ exports.updateDocument = updateDocument;
2332
2359
  exports.updateHeader = updateHeader;
2333
2360
  exports.validateOperations = validateOperations;
2334
2361
  exports.zod = zod;
2335
- //# sourceMappingURL=object-_zq9luMS.js.map
2362
+ //# sourceMappingURL=object-op6YzhH1.js.map