@verdant-web/common 2.7.3 → 2.9.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 (52) hide show
  1. package/dist/esm/authz.js.map +1 -1
  2. package/dist/esm/baseline.d.ts +2 -1
  3. package/dist/esm/diffing.d.ts +40 -0
  4. package/dist/esm/diffing.js +317 -0
  5. package/dist/esm/diffing.js.map +1 -0
  6. package/dist/esm/diffing.test.d.ts +1 -0
  7. package/dist/esm/diffing.test.js +1680 -0
  8. package/dist/esm/diffing.test.js.map +1 -0
  9. package/dist/esm/index.d.ts +20 -19
  10. package/dist/esm/index.js +17 -16
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/esm/oids.d.ts +5 -0
  13. package/dist/esm/oids.js +23 -1
  14. package/dist/esm/oids.js.map +1 -1
  15. package/dist/esm/operation.d.ts +11 -24
  16. package/dist/esm/operation.js +32 -270
  17. package/dist/esm/operation.js.map +1 -1
  18. package/dist/esm/operation.test.js +122 -592
  19. package/dist/esm/operation.test.js.map +1 -1
  20. package/dist/esm/patch.d.ts +19 -15
  21. package/dist/esm/patch.js +79 -18
  22. package/dist/esm/patch.js.map +1 -1
  23. package/dist/esm/schema/validation.d.ts +8 -1
  24. package/dist/esm/schema/validation.js +133 -63
  25. package/dist/esm/schema/validation.js.map +1 -1
  26. package/dist/esm/schema/validation.test.d.ts +1 -0
  27. package/dist/esm/schema/validation.test.js +60 -0
  28. package/dist/esm/schema/validation.test.js.map +1 -0
  29. package/dist/esm/timestamp.d.ts +1 -0
  30. package/dist/esm/timestamp.js +3 -0
  31. package/dist/esm/timestamp.js.map +1 -1
  32. package/dist/esm/undo.d.ts +2 -1
  33. package/dist/esm/undo.js +53 -146
  34. package/dist/esm/undo.js.map +1 -1
  35. package/dist/esm/undo.test.d.ts +1 -0
  36. package/dist/esm/undo.test.js +81 -0
  37. package/dist/esm/undo.test.js.map +1 -0
  38. package/package.json +1 -1
  39. package/src/authz.ts +2 -0
  40. package/src/baseline.ts +3 -1
  41. package/src/diffing.test.ts +1803 -0
  42. package/src/diffing.ts +402 -0
  43. package/src/index.ts +21 -20
  44. package/src/oids.ts +23 -1
  45. package/src/operation.test.ts +148 -623
  46. package/src/operation.ts +45 -378
  47. package/src/patch.ts +146 -14
  48. package/src/schema/validation.test.ts +66 -0
  49. package/src/schema/validation.ts +156 -73
  50. package/src/timestamp.ts +4 -1
  51. package/src/undo.test.ts +100 -0
  52. package/src/undo.ts +83 -144
package/dist/esm/undo.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { applyPatch } from './operation.js';
2
+ import { PatchCreator } from './patch.js';
3
+ import { isRef } from './refs.js';
2
4
  import { cloneDeep } from './utils.js';
3
- export function getUndoOperations(oid, initial, operations, getNow) {
5
+ export function getUndoOperations(oid, initial, operations, getNow, getSubId, authz) {
6
+ const patchCreator = new PatchCreator(getNow, getSubId);
4
7
  if (initial === undefined || initial === null) {
5
8
  // if the initial state is nothing, then the undo is to delete everything.
6
9
  // there's nothing else to worry about!
@@ -11,6 +14,7 @@ export function getUndoOperations(oid, initial, operations, getNow) {
11
14
  data: {
12
15
  op: 'delete',
13
16
  },
17
+ authz,
14
18
  },
15
19
  ];
16
20
  }
@@ -20,190 +24,93 @@ export function getUndoOperations(oid, initial, operations, getNow) {
20
24
  let state = cloneDeep(initial);
21
25
  const undoOperations = [];
22
26
  for (const operation of operations) {
23
- const undo = getUndoOperation(oid, state, operation, getNow);
27
+ const undo = getUndoOperation(oid, state, operation, patchCreator, authz);
24
28
  undoOperations.unshift(...undo);
25
29
  applyPatch(state, operation.data);
26
30
  }
27
31
  return undoOperations;
28
32
  }
29
- function getUndoOperation(oid, initial, operation, getNow) {
33
+ function getUndoOperation(oid, initial, operation, patchCreator, authz) {
34
+ var _a, _b;
30
35
  const data = operation.data;
31
36
  switch (data.op) {
32
37
  case 'set':
38
+ if (initial[data.name] === undefined) {
39
+ return patchCreator.createRemove(oid, data.name, authz);
40
+ }
41
+ return patchCreator.createSet(oid, data.name, initial[data.name], authz);
33
42
  case 'remove':
34
- return [
35
- {
36
- oid,
37
- timestamp: getNow(),
38
- data: {
39
- op: 'set',
40
- name: data.name,
41
- value: initial[data.name],
42
- },
43
- },
44
- ];
43
+ if (initial[data.name] === undefined) {
44
+ return [];
45
+ }
46
+ return patchCreator.createSet(oid, data.name, initial[data.name], authz);
45
47
  case 'list-insert':
46
- return [
47
- {
48
- oid,
49
- timestamp: getNow(),
50
- data: {
51
- op: 'list-delete',
52
- index: data.index,
53
- count: 1,
54
- },
55
- },
56
- ];
48
+ if (data.value === undefined && ((_a = data.values) === null || _a === void 0 ? void 0 : _a.length) === 0)
49
+ return [];
50
+ return patchCreator.createListDelete(oid, data.index, data.value ? 1 : ((_b = data.values) === null || _b === void 0 ? void 0 : _b.length) || 0, authz);
57
51
  case 'list-delete':
58
- return [
59
- {
60
- oid,
61
- timestamp: getNow(),
62
- data: {
63
- op: 'list-insert',
64
- index: data.index,
65
- values: initial.slice(data.index, data.count),
66
- },
67
- },
68
- ];
52
+ return patchCreator.createListInsertMany(oid, data.index, initial.slice(data.index, data.index + data.count), authz);
69
53
  case 'list-move-by-ref':
70
- return [
71
- {
72
- oid,
73
- timestamp: getNow(),
74
- data: {
75
- op: 'list-move-by-ref',
76
- value: data.value,
77
- index: initial.indexOf(data.value),
78
- },
79
- },
80
- ];
54
+ return patchCreator.createListMoveByRef(oid, data.value, findItemRefIndex(initial, data.value), authz);
81
55
  case 'list-move-by-index':
82
- return [
83
- {
84
- oid,
85
- timestamp: getNow(),
86
- data: {
87
- op: 'list-move-by-index',
88
- from: data.to,
89
- to: data.from,
90
- },
91
- },
92
- ];
56
+ return patchCreator.createListMoveByIndex(oid, data.to, data.from, authz);
93
57
  case 'delete':
94
- return [
95
- {
96
- oid,
97
- timestamp: getNow(),
98
- data: {
99
- op: 'initialize',
100
- value: initial,
101
- },
102
- },
103
- ];
58
+ return patchCreator.createInitialize(initial, oid, authz, true);
104
59
  case 'list-push':
105
- return [
106
- {
107
- oid,
108
- timestamp: getNow(),
109
- data: {
110
- op: 'list-remove',
111
- value: data.value,
112
- // best heuristic here - remove the last instance of the item.
113
- only: 'last',
114
- },
115
- },
116
- ];
60
+ return patchCreator.createListRemove(oid, data.value, 'last', authz);
117
61
  case 'list-remove':
118
62
  if (data.only === 'last') {
119
- const index = initial.lastIndexOf(data.value);
120
- return [
121
- {
122
- oid,
123
- timestamp: getNow(),
124
- data: {
125
- op: 'list-insert',
126
- index,
127
- values: [data.value],
128
- },
129
- },
130
- ];
63
+ const index = findItemRefIndex(initial, data.value, 0, 'backward');
64
+ if (index === -1) {
65
+ // if the value isn't in the list, then there's nothing to undo.
66
+ return [];
67
+ }
68
+ return patchCreator.createListInsert(oid, index, data.value, authz);
131
69
  }
132
70
  else if (data.only === 'first') {
133
- const index = initial.indexOf(data.value);
134
- return [
135
- {
136
- oid,
137
- timestamp: getNow(),
138
- data: {
139
- op: 'list-insert',
140
- index,
141
- values: [data.value],
142
- },
143
- },
144
- ];
71
+ const index = findItemRefIndex(initial, data.value);
72
+ if (index === -1) {
73
+ // if the value isn't in the list, then there's nothing to undo.
74
+ return [];
75
+ }
76
+ return patchCreator.createListInsert(oid, index, data.value, authz);
145
77
  }
146
78
  else {
147
79
  // find all instances of value and restore them at their
148
80
  // original index
149
81
  const indexesOfValue = [];
150
- let index = initial.indexOf(data.value);
82
+ let index = findItemRefIndex(initial, data.value);
151
83
  while (index !== -1) {
152
84
  indexesOfValue.push(index);
153
- index = initial.indexOf(data.value, index + 1);
85
+ index = findItemRefIndex(initial, data.value, index + 1);
154
86
  }
155
- return indexesOfValue.map((index) => ({
156
- oid,
157
- timestamp: getNow(),
158
- data: {
159
- op: 'list-insert',
160
- index,
161
- value: data.value,
162
- },
163
- }));
87
+ return indexesOfValue.flatMap((index) => patchCreator.createListInsert(oid, index, data.value, authz));
164
88
  }
165
89
  case 'list-add':
166
90
  // this one is kind of ambiguous. in theory the set may have
167
91
  // already included the value and so no change happened. but
168
92
  // basically we infer the intent is to remove what was meant
169
93
  // to be added by this change.
170
- return [
171
- {
172
- oid,
173
- timestamp: getNow(),
174
- data: {
175
- op: 'list-remove',
176
- value: data.value,
177
- only: 'last',
178
- },
179
- },
180
- ];
94
+ return patchCreator.createListRemove(oid, data.value, 'last', authz);
181
95
  case 'list-set':
182
- return [
183
- {
184
- oid,
185
- timestamp: getNow(),
186
- data: {
187
- op: 'list-set',
188
- index: data.index,
189
- value: initial[data.index],
190
- },
191
- },
192
- ];
96
+ if (initial[data.index] !== undefined) {
97
+ return patchCreator.createListSet(oid, data.index, initial[data.index], authz);
98
+ }
99
+ return patchCreator.createListDelete(oid, data.index, 1, authz);
193
100
  case 'initialize':
194
- return [
195
- {
196
- oid,
197
- timestamp: getNow(),
198
- data: {
199
- op: 'delete',
200
- },
201
- },
202
- ];
101
+ return patchCreator.createDelete(oid, authz);
203
102
  case 'touch':
204
103
  return [];
205
104
  default:
206
105
  throw new Error(`Cannot undo operation type: ${data.op}`);
207
106
  }
208
107
  }
108
+ function findItemRefIndex(list, item, from = 0, dir = 'forward') {
109
+ const method = dir === 'forward' ? 'findIndex' : 'findLastIndex';
110
+ // for object items, attempt to find the matching item by OID.
111
+ if (isRef(item)) {
112
+ return list[method]((i, idx) => isRef(i) && i.id === item.id && idx >= from);
113
+ }
114
+ return list[method]((i, idx) => i === item && idx >= from);
115
+ }
209
116
  //# sourceMappingURL=undo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"undo.js","sourceRoot":"","sources":["../../src/undo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAa,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,UAAU,iBAAiB,CAChC,GAAqB,EACrB,OAAY,EACZ,UAAuB,EACvB,MAAoB;IAEpB,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC/C,0EAA0E;QAC1E,uCAAuC;QACvC,OAAO;YACN;gBACC,GAAG;gBACH,SAAS,EAAE,MAAM,EAAE;gBACnB,IAAI,EAAE;oBACL,EAAE,EAAE,QAAQ;iBACZ;aACD;SACD,CAAC;IACH,CAAC;IACD,iDAAiD;IACjD,wDAAwD;IACxD,8BAA8B;IAC9B,IAAI,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,cAAc,GAAgB,EAAE,CAAC;IACvC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC7D,cAAc,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QAChC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,cAAc,CAAC;AACvB,CAAC;AAED,SAAS,gBAAgB,CACxB,GAAqB,EACrB,OAAY,EACZ,SAAoB,EACpB,MAAoB;IAEpB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAC5B,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;QACjB,KAAK,KAAK,CAAC;QACX,KAAK,QAAQ;YACZ,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,KAAK;wBACT,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;qBACzB;iBACD;aACD,CAAC;QACH,KAAK,aAAa;YACjB,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,aAAa;wBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,KAAK,EAAE,CAAC;qBACR;iBACD;aACD,CAAC;QACH,KAAK,aAAa;YACjB,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,aAAa;wBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC;qBAC7C;iBACD;aACD,CAAC;QACH,KAAK,kBAAkB;YACtB,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,kBAAkB;wBACtB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;qBAClC;iBACD;aACD,CAAC;QACH,KAAK,oBAAoB;YACxB,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,oBAAoB;wBACxB,IAAI,EAAE,IAAI,CAAC,EAAE;wBACb,EAAE,EAAE,IAAI,CAAC,IAAI;qBACb;iBACD;aACD,CAAC;QACH,KAAK,QAAQ;YACZ,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,YAAY;wBAChB,KAAK,EAAE,OAAO;qBACd;iBACD;aACD,CAAC;QACH,KAAK,WAAW;YACf,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,aAAa;wBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,8DAA8D;wBAC9D,IAAI,EAAE,MAAM;qBACZ;iBACD;aACD,CAAC;QACH,KAAK,aAAa;YACjB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,OAAO;oBACN;wBACC,GAAG;wBACH,SAAS,EAAE,MAAM,EAAE;wBACnB,IAAI,EAAE;4BACL,EAAE,EAAE,aAAa;4BACjB,KAAK;4BACL,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;yBACpB;qBACD;iBACD,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAClC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1C,OAAO;oBACN;wBACC,GAAG;wBACH,SAAS,EAAE,MAAM,EAAE;wBACnB,IAAI,EAAE;4BACL,EAAE,EAAE,aAAa;4BACjB,KAAK;4BACL,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;yBACpB;qBACD;iBACD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,wDAAwD;gBACxD,iBAAiB;gBACjB,MAAM,cAAc,GAAG,EAAE,CAAC;gBAC1B,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxC,OAAO,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACrB,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC3B,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAChD,CAAC;gBACD,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACrC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,aAAa;wBACjB,KAAK;wBACL,KAAK,EAAE,IAAI,CAAC,KAAK;qBACjB;iBACD,CAAC,CAAC,CAAC;YACL,CAAC;QACF,KAAK,UAAU;YACd,4DAA4D;YAC5D,4DAA4D;YAC5D,4DAA4D;YAC5D,8BAA8B;YAC9B,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,aAAa;wBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,IAAI,EAAE,MAAM;qBACZ;iBACD;aACD,CAAC;QACH,KAAK,UAAU;YACd,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,UAAU;wBACd,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;qBAC1B;iBACD;aACD,CAAC;QACH,KAAK,YAAY;YAChB,OAAO;gBACN;oBACC,GAAG;oBACH,SAAS,EAAE,MAAM,EAAE;oBACnB,IAAI,EAAE;wBACL,EAAE,EAAE,QAAQ;qBACZ;iBACD;aACD,CAAC;QACH,KAAK,OAAO;YACX,OAAO,EAAE,CAAC;QACX;YACC,MAAM,IAAI,KAAK,CAAC,+BAAgC,IAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"undo.js","sourceRoot":"","sources":["../../src/undo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,81 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { assignOid, createOid, createRef } from './oids.js';
3
+ import { PatchCreator } from './patch.js';
4
+ import { getUndoOperations } from './undo.js';
5
+ function createClock(start = 0) {
6
+ let time = start;
7
+ function clock() {
8
+ return `${time++}`;
9
+ }
10
+ clock.reset = () => {
11
+ time = start;
12
+ };
13
+ return clock;
14
+ }
15
+ describe('undo', () => {
16
+ it('correctly removes added list items', () => {
17
+ const clock = createClock();
18
+ const patchCreator = new PatchCreator(clock, createClock());
19
+ const initial = [1, 2];
20
+ const oid = createOid('test', 'foo');
21
+ const operations = patchCreator.createListSet(oid, 2, 3);
22
+ clock.reset();
23
+ const undos = getUndoOperations(oid, initial, operations, clock);
24
+ clock.reset();
25
+ expect(undos).toEqual(patchCreator.createListDelete(oid, 2, 1));
26
+ });
27
+ it('correctly restores removed items by ref', () => {
28
+ const clock = createClock();
29
+ const patchCreator = new PatchCreator(clock, createClock());
30
+ const initial = assignOid([createRef('test/a:1'), createRef('test/a:2'), createRef('test/a:3')], 'test/a');
31
+ const operations = patchCreator.createListRemove('test/a', initial[1], 'last');
32
+ clock.reset();
33
+ const undos = getUndoOperations('test/a', initial, operations, clock);
34
+ clock.reset();
35
+ expect(undos).toEqual(patchCreator.createListInsert('test/a', 1, initial[1]));
36
+ });
37
+ it('undoes list insert with 1 item', () => {
38
+ const clock = createClock();
39
+ const patchCreator = new PatchCreator(clock, createClock());
40
+ const initial = [1, 2];
41
+ const oid = createOid('test', 'foo');
42
+ const operations = patchCreator.createListInsert(oid, 1, 3);
43
+ clock.reset();
44
+ const undos = getUndoOperations(oid, initial, operations, clock);
45
+ clock.reset();
46
+ expect(undos).toEqual(patchCreator.createListDelete(oid, 1, 1));
47
+ });
48
+ it('undoes list insert with multiple items', () => {
49
+ const clock = createClock();
50
+ const patchCreator = new PatchCreator(clock, createClock());
51
+ const initial = [1, 2];
52
+ const oid = createOid('test', 'foo');
53
+ const operations = patchCreator.createListInsertMany(oid, 1, [3, 4]);
54
+ clock.reset();
55
+ const undos = getUndoOperations(oid, initial, operations, clock);
56
+ clock.reset();
57
+ expect(undos).toEqual(patchCreator.createListDelete(oid, 1, 2));
58
+ });
59
+ it('undoes initialize with delete', () => {
60
+ const clock = createClock();
61
+ const patchCreator = new PatchCreator(clock, createClock());
62
+ const initial = { foo: 'bar' };
63
+ const oid = createOid('test', 'foo');
64
+ const operations = patchCreator.createInitialize(initial, oid);
65
+ clock.reset();
66
+ const undos = getUndoOperations(oid, initial, operations, clock);
67
+ clock.reset();
68
+ expect(undos).toEqual(patchCreator.createDelete(oid));
69
+ });
70
+ it('undoes an object move by ref', () => {
71
+ const clock = createClock();
72
+ const patchCreator = new PatchCreator(clock, createClock());
73
+ const initial = assignOid([createRef('test/a:1'), createRef('test/a:2'), createRef('test/a:3')], 'test/a');
74
+ const operations = patchCreator.createListMoveByRef('test/a', initial[1], 0);
75
+ clock.reset();
76
+ const undos = getUndoOperations('test/a', initial, operations, clock);
77
+ clock.reset();
78
+ expect(undos).toEqual(patchCreator.createListMoveByRef('test/a', initial[1], 1));
79
+ });
80
+ });
81
+ //# sourceMappingURL=undo.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"undo.test.js","sourceRoot":"","sources":["../../src/undo.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdant-web/common",
3
- "version": "2.7.3",
3
+ "version": "2.9.0",
4
4
  "access": "public",
5
5
  "type": "module",
6
6
  "exports": {
package/src/authz.ts CHANGED
@@ -18,6 +18,8 @@ function decode(str: string): string {
18
18
  }
19
19
 
20
20
  export type AuthorizationKey = string & {
21
+ // virtual type only used for type checking to try to sort
22
+ // out between encoded and decoded string values.
21
23
  '@@type': 'authz';
22
24
  };
23
25
 
package/src/baseline.ts CHANGED
@@ -2,9 +2,11 @@
2
2
  // written upon rebasing. If you apply ops to an undefined
3
3
  // snapshot without an initialize, it remains undefined.
4
4
 
5
+ import { AuthorizationKey } from './authz.js';
6
+
5
7
  export type DocumentBaseline<T extends any = any> = {
6
8
  oid: string;
7
9
  snapshot: T;
8
10
  timestamp: string;
9
- authz?: string;
11
+ authz?: AuthorizationKey;
10
12
  };