@verdant-web/common 1.11.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 (241) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/EventSubscriber.d.ts +17 -0
  3. package/dist/cjs/EventSubscriber.js +67 -0
  4. package/dist/cjs/EventSubscriber.js.map +1 -0
  5. package/dist/cjs/baseline.d.ts +5 -0
  6. package/dist/cjs/baseline.js +3 -0
  7. package/dist/cjs/baseline.js.map +1 -0
  8. package/dist/cjs/batching.d.ts +41 -0
  9. package/dist/cjs/batching.js +89 -0
  10. package/dist/cjs/batching.js.map +1 -0
  11. package/dist/cjs/files.d.ts +19 -0
  12. package/dist/cjs/files.js +19 -0
  13. package/dist/cjs/files.js.map +1 -0
  14. package/dist/cjs/files.test.d.ts +1 -0
  15. package/dist/cjs/files.test.js +81 -0
  16. package/dist/cjs/files.test.js.map +1 -0
  17. package/dist/cjs/index.d.ts +18 -0
  18. package/dist/cjs/index.js +36 -0
  19. package/dist/cjs/index.js.map +1 -0
  20. package/dist/cjs/indexes.d.ts +14 -0
  21. package/dist/cjs/indexes.js +116 -0
  22. package/dist/cjs/indexes.js.map +1 -0
  23. package/dist/cjs/indexes.test.d.ts +1 -0
  24. package/dist/cjs/indexes.test.js +128 -0
  25. package/dist/cjs/indexes.test.js.map +1 -0
  26. package/dist/cjs/migration.d.ts +98 -0
  27. package/dist/cjs/migration.js +128 -0
  28. package/dist/cjs/migration.js.map +1 -0
  29. package/dist/cjs/oids.d.ts +87 -0
  30. package/dist/cjs/oids.js +375 -0
  31. package/dist/cjs/oids.js.map +1 -0
  32. package/dist/cjs/oids.test.d.ts +1 -0
  33. package/dist/cjs/oids.test.js +282 -0
  34. package/dist/cjs/oids.test.js.map +1 -0
  35. package/dist/cjs/operation.d.ts +139 -0
  36. package/dist/cjs/operation.js +533 -0
  37. package/dist/cjs/operation.js.map +1 -0
  38. package/dist/cjs/operation.test.d.ts +1 -0
  39. package/dist/cjs/operation.test.js +827 -0
  40. package/dist/cjs/operation.test.js.map +1 -0
  41. package/dist/cjs/patch.d.ts +26 -0
  42. package/dist/cjs/patch.js +227 -0
  43. package/dist/cjs/patch.js.map +1 -0
  44. package/dist/cjs/presence.d.ts +27 -0
  45. package/dist/cjs/presence.js +3 -0
  46. package/dist/cjs/presence.js.map +1 -0
  47. package/dist/cjs/protocol.d.ts +145 -0
  48. package/dist/cjs/protocol.js +4 -0
  49. package/dist/cjs/protocol.js.map +1 -0
  50. package/dist/cjs/refs.d.ts +5 -0
  51. package/dist/cjs/refs.js +22 -0
  52. package/dist/cjs/refs.js.map +1 -0
  53. package/dist/cjs/replica.d.ts +28 -0
  54. package/dist/cjs/replica.js +29 -0
  55. package/dist/cjs/replica.js.map +1 -0
  56. package/dist/cjs/schema/defaults.d.ts +4 -0
  57. package/dist/cjs/schema/defaults.js +72 -0
  58. package/dist/cjs/schema/defaults.js.map +1 -0
  59. package/dist/cjs/schema/defaults.test.d.ts +1 -0
  60. package/dist/cjs/schema/defaults.test.js +21 -0
  61. package/dist/cjs/schema/defaults.test.js.map +1 -0
  62. package/dist/cjs/schema/index.d.ts +8 -0
  63. package/dist/cjs/schema/index.js +29 -0
  64. package/dist/cjs/schema/index.js.map +1 -0
  65. package/dist/cjs/schema/indexFilters.d.ts +6 -0
  66. package/dist/cjs/schema/indexFilters.js +31 -0
  67. package/dist/cjs/schema/indexFilters.js.map +1 -0
  68. package/dist/cjs/schema/types/collection.d.ts +51 -0
  69. package/dist/cjs/schema/types/collection.js +3 -0
  70. package/dist/cjs/schema/types/collection.js.map +1 -0
  71. package/dist/cjs/schema/types/compounds.d.ts +12 -0
  72. package/dist/cjs/schema/types/compounds.js +3 -0
  73. package/dist/cjs/schema/types/compounds.js.map +1 -0
  74. package/dist/cjs/schema/types/fields.d.ts +59 -0
  75. package/dist/cjs/schema/types/fields.js +3 -0
  76. package/dist/cjs/schema/types/fields.js.map +1 -0
  77. package/dist/cjs/schema/types/filters.d.ts +29 -0
  78. package/dist/cjs/schema/types/filters.js +3 -0
  79. package/dist/cjs/schema/types/filters.js.map +1 -0
  80. package/dist/cjs/schema/types/shapes.d.ts +21 -0
  81. package/dist/cjs/schema/types/shapes.js +3 -0
  82. package/dist/cjs/schema/types/shapes.js.map +1 -0
  83. package/dist/cjs/schema/types/synthetics.d.ts +28 -0
  84. package/dist/cjs/schema/types/synthetics.js +3 -0
  85. package/dist/cjs/schema/types/synthetics.js.map +1 -0
  86. package/dist/cjs/schema/types.d.ts +18 -0
  87. package/dist/cjs/schema/types.js +23 -0
  88. package/dist/cjs/schema/types.js.map +1 -0
  89. package/dist/cjs/timestamp.d.ts +48 -0
  90. package/dist/cjs/timestamp.js +244 -0
  91. package/dist/cjs/timestamp.js.map +1 -0
  92. package/dist/cjs/timestamp.test.d.ts +1 -0
  93. package/dist/cjs/timestamp.test.js +94 -0
  94. package/dist/cjs/timestamp.test.js.map +1 -0
  95. package/dist/cjs/undo.d.ts +3 -0
  96. package/dist/cjs/undo.js +199 -0
  97. package/dist/cjs/undo.js.map +1 -0
  98. package/dist/cjs/utils.d.ts +15 -0
  99. package/dist/cjs/utils.js +128 -0
  100. package/dist/cjs/utils.js.map +1 -0
  101. package/dist/cjs/utils.test.d.ts +1 -0
  102. package/dist/cjs/utils.test.js +37 -0
  103. package/dist/cjs/utils.test.js.map +1 -0
  104. package/dist/esm/EventSubscriber.d.ts +17 -0
  105. package/dist/esm/EventSubscriber.js +63 -0
  106. package/dist/esm/EventSubscriber.js.map +1 -0
  107. package/dist/esm/baseline.d.ts +5 -0
  108. package/dist/esm/baseline.js +2 -0
  109. package/dist/esm/baseline.js.map +1 -0
  110. package/dist/esm/batching.d.ts +41 -0
  111. package/dist/esm/batching.js +84 -0
  112. package/dist/esm/batching.js.map +1 -0
  113. package/dist/esm/files.d.ts +19 -0
  114. package/dist/esm/files.js +13 -0
  115. package/dist/esm/files.js.map +1 -0
  116. package/dist/esm/files.test.d.ts +1 -0
  117. package/dist/esm/files.test.js +79 -0
  118. package/dist/esm/files.test.js.map +1 -0
  119. package/dist/esm/index.d.ts +18 -0
  120. package/dist/esm/index.js +16 -0
  121. package/dist/esm/index.js.map +1 -0
  122. package/dist/esm/indexes.d.ts +14 -0
  123. package/dist/esm/indexes.js +106 -0
  124. package/dist/esm/indexes.js.map +1 -0
  125. package/dist/esm/indexes.test.d.ts +1 -0
  126. package/dist/esm/indexes.test.js +126 -0
  127. package/dist/esm/indexes.test.js.map +1 -0
  128. package/dist/esm/migration.d.ts +98 -0
  129. package/dist/esm/migration.js +122 -0
  130. package/dist/esm/migration.js.map +1 -0
  131. package/dist/esm/oids.d.ts +87 -0
  132. package/dist/esm/oids.js +348 -0
  133. package/dist/esm/oids.js.map +1 -0
  134. package/dist/esm/oids.test.d.ts +1 -0
  135. package/dist/esm/oids.test.js +280 -0
  136. package/dist/esm/oids.test.js.map +1 -0
  137. package/dist/esm/operation.d.ts +139 -0
  138. package/dist/esm/operation.js +518 -0
  139. package/dist/esm/operation.js.map +1 -0
  140. package/dist/esm/operation.test.d.ts +1 -0
  141. package/dist/esm/operation.test.js +825 -0
  142. package/dist/esm/operation.test.js.map +1 -0
  143. package/dist/esm/patch.d.ts +26 -0
  144. package/dist/esm/patch.js +223 -0
  145. package/dist/esm/patch.js.map +1 -0
  146. package/dist/esm/presence.d.ts +27 -0
  147. package/dist/esm/presence.js +2 -0
  148. package/dist/esm/presence.js.map +1 -0
  149. package/dist/esm/protocol.d.ts +145 -0
  150. package/dist/esm/protocol.js +3 -0
  151. package/dist/esm/protocol.js.map +1 -0
  152. package/dist/esm/refs.d.ts +5 -0
  153. package/dist/esm/refs.js +17 -0
  154. package/dist/esm/refs.js.map +1 -0
  155. package/dist/esm/replica.d.ts +28 -0
  156. package/dist/esm/replica.js +26 -0
  157. package/dist/esm/replica.js.map +1 -0
  158. package/dist/esm/schema/defaults.d.ts +4 -0
  159. package/dist/esm/schema/defaults.js +66 -0
  160. package/dist/esm/schema/defaults.js.map +1 -0
  161. package/dist/esm/schema/defaults.test.d.ts +1 -0
  162. package/dist/esm/schema/defaults.test.js +19 -0
  163. package/dist/esm/schema/defaults.test.js.map +1 -0
  164. package/dist/esm/schema/index.d.ts +8 -0
  165. package/dist/esm/schema/index.js +10 -0
  166. package/dist/esm/schema/index.js.map +1 -0
  167. package/dist/esm/schema/indexFilters.d.ts +6 -0
  168. package/dist/esm/schema/indexFilters.js +23 -0
  169. package/dist/esm/schema/indexFilters.js.map +1 -0
  170. package/dist/esm/schema/types/collection.d.ts +51 -0
  171. package/dist/esm/schema/types/collection.js +2 -0
  172. package/dist/esm/schema/types/collection.js.map +1 -0
  173. package/dist/esm/schema/types/compounds.d.ts +12 -0
  174. package/dist/esm/schema/types/compounds.js +2 -0
  175. package/dist/esm/schema/types/compounds.js.map +1 -0
  176. package/dist/esm/schema/types/fields.d.ts +59 -0
  177. package/dist/esm/schema/types/fields.js +2 -0
  178. package/dist/esm/schema/types/fields.js.map +1 -0
  179. package/dist/esm/schema/types/filters.d.ts +29 -0
  180. package/dist/esm/schema/types/filters.js +2 -0
  181. package/dist/esm/schema/types/filters.js.map +1 -0
  182. package/dist/esm/schema/types/shapes.d.ts +21 -0
  183. package/dist/esm/schema/types/shapes.js +2 -0
  184. package/dist/esm/schema/types/shapes.js.map +1 -0
  185. package/dist/esm/schema/types/synthetics.d.ts +28 -0
  186. package/dist/esm/schema/types/synthetics.js +2 -0
  187. package/dist/esm/schema/types/synthetics.js.map +1 -0
  188. package/dist/esm/schema/types.d.ts +18 -0
  189. package/dist/esm/schema/types.js +7 -0
  190. package/dist/esm/schema/types.js.map +1 -0
  191. package/dist/esm/timestamp.d.ts +48 -0
  192. package/dist/esm/timestamp.js +229 -0
  193. package/dist/esm/timestamp.js.map +1 -0
  194. package/dist/esm/timestamp.test.d.ts +1 -0
  195. package/dist/esm/timestamp.test.js +92 -0
  196. package/dist/esm/timestamp.test.js.map +1 -0
  197. package/dist/esm/undo.d.ts +3 -0
  198. package/dist/esm/undo.js +195 -0
  199. package/dist/esm/undo.js.map +1 -0
  200. package/dist/esm/utils.d.ts +15 -0
  201. package/dist/esm/utils.js +114 -0
  202. package/dist/esm/utils.js.map +1 -0
  203. package/dist/esm/utils.test.d.ts +1 -0
  204. package/dist/esm/utils.test.js +35 -0
  205. package/dist/esm/utils.test.js.map +1 -0
  206. package/dist/tsconfig-cjs.tsbuildinfo +1 -0
  207. package/dist/tsconfig.tsbuildinfo +1 -0
  208. package/package.json +38 -0
  209. package/src/EventSubscriber.ts +81 -0
  210. package/src/baseline.ts +9 -0
  211. package/src/batching.ts +135 -0
  212. package/src/files.ts +34 -0
  213. package/src/index.ts +26 -0
  214. package/src/indexes.test.ts +158 -0
  215. package/src/indexes.ts +151 -0
  216. package/src/migration.ts +391 -0
  217. package/src/oids.test.ts +395 -0
  218. package/src/oids.ts +442 -0
  219. package/src/operation.test.ts +966 -0
  220. package/src/operation.ts +755 -0
  221. package/src/patch.ts +277 -0
  222. package/src/presence.ts +29 -0
  223. package/src/protocol.ts +184 -0
  224. package/src/refs.ts +16 -0
  225. package/src/replica.ts +29 -0
  226. package/src/schema/defaults.test.ts +19 -0
  227. package/src/schema/defaults.ts +72 -0
  228. package/src/schema/index.ts +28 -0
  229. package/src/schema/indexFilters.ts +49 -0
  230. package/src/schema/types/collection.ts +133 -0
  231. package/src/schema/types/compounds.ts +33 -0
  232. package/src/schema/types/fields.ts +85 -0
  233. package/src/schema/types/filters.ts +39 -0
  234. package/src/schema/types/shapes.ts +83 -0
  235. package/src/schema/types/synthetics.ts +45 -0
  236. package/src/schema/types.ts +28 -0
  237. package/src/timestamp.test.ts +113 -0
  238. package/src/timestamp.ts +284 -0
  239. package/src/undo.ts +205 -0
  240. package/src/utils.test.ts +38 -0
  241. package/src/utils.ts +137 -0
@@ -0,0 +1,827 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const files_js_1 = require("./files.js");
5
+ const oids_js_1 = require("./oids.js");
6
+ const operation_js_1 = require("./operation.js");
7
+ function createClock(init = 0) {
8
+ let i = init;
9
+ return () => (i++).toString();
10
+ }
11
+ (0, vitest_1.describe)('creating diff patch operations', () => {
12
+ (0, vitest_1.describe)('on flat objects', () => {
13
+ (0, vitest_1.it)('generates and applies set and remove operations', () => {
14
+ const from = { foo: 'bar', baz: 'qux', zing: 1 };
15
+ (0, oids_js_1.assignOid)(from, 'test/a');
16
+ const to = { foo: 'bar', baz: 'pop' };
17
+ (0, oids_js_1.assignOid)(to, 'test/a');
18
+ const ops = (0, operation_js_1.diffToPatches)(from, to, createClock(), []);
19
+ (0, vitest_1.expect)(ops).toMatchInlineSnapshot(`
20
+ [
21
+ {
22
+ "data": {
23
+ "name": "baz",
24
+ "op": "set",
25
+ "value": "pop",
26
+ },
27
+ "oid": "test/a",
28
+ "timestamp": "0",
29
+ },
30
+ {
31
+ "data": {
32
+ "name": "zing",
33
+ "op": "remove",
34
+ },
35
+ "oid": "test/a",
36
+ "timestamp": "1",
37
+ },
38
+ ]
39
+ `);
40
+ const result = (0, operation_js_1.applyOperations)(from, ops);
41
+ (0, vitest_1.expect)(result).toEqual(to);
42
+ });
43
+ });
44
+ (0, vitest_1.describe)('on nested objects', () => {
45
+ (0, vitest_1.it)('replaces whole nested objects', () => {
46
+ const from = (0, oids_js_1.assignOid)({
47
+ foo: 'bar',
48
+ baz: (0, oids_js_1.assignOid)({ qux: 'corge' }, 'test/a:0'),
49
+ }, 'test/a');
50
+ const to = (0, oids_js_1.assignOid)({
51
+ foo: 'bar',
52
+ baz: (0, oids_js_1.assignOid)({ qux: 'grault' }, 'test/a:1'),
53
+ }, 'test/a');
54
+ const patches = (0, operation_js_1.diffToPatches)(from, to, createClock(), []);
55
+ (0, vitest_1.expect)(patches).toMatchInlineSnapshot(`
56
+ [
57
+ {
58
+ "data": {
59
+ "op": "initialize",
60
+ "value": {
61
+ "qux": "grault",
62
+ },
63
+ },
64
+ "oid": "test/a:1",
65
+ "timestamp": "0",
66
+ },
67
+ {
68
+ "data": {
69
+ "name": "baz",
70
+ "op": "set",
71
+ "value": {
72
+ "@@type": "ref",
73
+ "id": "test/a:1",
74
+ },
75
+ },
76
+ "oid": "test/a",
77
+ "timestamp": "1",
78
+ },
79
+ {
80
+ "data": {
81
+ "op": "delete",
82
+ },
83
+ "oid": "test/a:0",
84
+ "timestamp": "2",
85
+ },
86
+ ]
87
+ `);
88
+ });
89
+ (0, vitest_1.it)('replaces whole nested objects with different ids even if fields are the same', () => {
90
+ const from = {
91
+ foo: 'bar',
92
+ baz: { qux: 'corge' },
93
+ };
94
+ (0, oids_js_1.assignOid)(from, 'test/a');
95
+ (0, oids_js_1.assignOid)(from.baz, 'test/a:0');
96
+ const to = {
97
+ foo: 'bar',
98
+ baz: { qux: 'corge' },
99
+ };
100
+ (0, oids_js_1.assignOid)(to, 'test/a');
101
+ (0, oids_js_1.assignOid)(to.baz, 'test/a:1');
102
+ const patches = (0, operation_js_1.diffToPatches)(from, to, createClock(), []);
103
+ (0, vitest_1.expect)(patches).toMatchInlineSnapshot(`
104
+ [
105
+ {
106
+ "data": {
107
+ "op": "initialize",
108
+ "value": {
109
+ "qux": "corge",
110
+ },
111
+ },
112
+ "oid": "test/a:1",
113
+ "timestamp": "0",
114
+ },
115
+ {
116
+ "data": {
117
+ "name": "baz",
118
+ "op": "set",
119
+ "value": {
120
+ "@@type": "ref",
121
+ "id": "test/a:1",
122
+ },
123
+ },
124
+ "oid": "test/a",
125
+ "timestamp": "1",
126
+ },
127
+ {
128
+ "data": {
129
+ "op": "delete",
130
+ },
131
+ "oid": "test/a:0",
132
+ "timestamp": "2",
133
+ },
134
+ ]
135
+ `);
136
+ });
137
+ (0, vitest_1.it)('does not replace objects with the same identity and same fields', () => {
138
+ const from = {
139
+ foo: 'bar',
140
+ baz: { qux: 'corge' },
141
+ };
142
+ (0, oids_js_1.assignOid)(from, 'test/a');
143
+ (0, oids_js_1.assignOid)(from.baz, 'test/a:0');
144
+ const to = {
145
+ foo: 'bar',
146
+ baz: { qux: 'corge' },
147
+ };
148
+ (0, oids_js_1.assignOid)(to, 'test/a');
149
+ (0, oids_js_1.assignOid)(to.baz, 'test/a:0');
150
+ const patches = (0, operation_js_1.diffToPatches)(from, to, createClock(), []);
151
+ (0, vitest_1.expect)(patches).toEqual([]);
152
+ });
153
+ (0, vitest_1.it)('patches sub-objects with same identity', () => {
154
+ const from = {
155
+ foo: 'bar',
156
+ baz: { qux: 'corge' },
157
+ };
158
+ (0, oids_js_1.assignOid)(from, 'test/a');
159
+ (0, oids_js_1.assignOid)(from.baz, 'test/a:0');
160
+ const to = {
161
+ foo: 'bar',
162
+ baz: { qux: 'fig' },
163
+ };
164
+ (0, oids_js_1.assignOid)(to, 'test/a');
165
+ (0, oids_js_1.assignOid)(to.baz, 'test/a:0');
166
+ const patches = (0, operation_js_1.diffToPatches)(from, to, createClock(), []);
167
+ (0, vitest_1.expect)(patches).toMatchInlineSnapshot(`
168
+ [
169
+ {
170
+ "data": {
171
+ "name": "qux",
172
+ "op": "set",
173
+ "value": "fig",
174
+ },
175
+ "oid": "test/a:0",
176
+ "timestamp": "0",
177
+ },
178
+ ]
179
+ `);
180
+ });
181
+ (0, vitest_1.it)('retains keys which are undefined in new object if defaultUndefined is set', () => {
182
+ const from = {
183
+ foo: 'bar',
184
+ baz: { qux: 'corge' },
185
+ };
186
+ (0, oids_js_1.assignOid)(from, 'test/a');
187
+ (0, oids_js_1.assignOid)(from.baz, 'test/a:0');
188
+ const to = {
189
+ foo: 'bip',
190
+ };
191
+ (0, oids_js_1.assignOid)(to, 'test/a');
192
+ const patches = (0, operation_js_1.diffToPatches)(from, to, createClock(), [], undefined, [], {
193
+ defaultUndefined: true,
194
+ mergeUnknownObjects: true,
195
+ });
196
+ (0, vitest_1.expect)(patches).toMatchInlineSnapshot(`
197
+ [
198
+ {
199
+ "data": {
200
+ "name": "foo",
201
+ "op": "set",
202
+ "value": "bip",
203
+ },
204
+ "oid": "test/a",
205
+ "timestamp": "0",
206
+ },
207
+ ]
208
+ `);
209
+ });
210
+ });
211
+ (0, vitest_1.describe)('on lists of primitives', () => {
212
+ (0, vitest_1.it)('pushes items', async () => {
213
+ (0, vitest_1.expect)((0, operation_js_1.applyOperations)((0, oids_js_1.assignOid)(['foo', 'bar'], 'test/a'), [
214
+ {
215
+ oid: 'test/a',
216
+ timestamp: 'meh',
217
+ data: {
218
+ op: 'list-push',
219
+ value: 'baz',
220
+ },
221
+ },
222
+ ])).toEqual((0, oids_js_1.assignOid)(['foo', 'bar', 'baz'], 'test/a'));
223
+ });
224
+ vitest_1.it.todo('sets items');
225
+ vitest_1.it.todo('inserts items');
226
+ vitest_1.it.todo('removes items by index');
227
+ vitest_1.it.todo('removes items by value');
228
+ vitest_1.it.todo('moves items by index');
229
+ vitest_1.it.todo('moves items by value');
230
+ });
231
+ vitest_1.describe.todo('on lists of objects', () => {
232
+ vitest_1.it.todo('pushes items');
233
+ vitest_1.it.todo('moves objects by identity');
234
+ vitest_1.it.todo('removes objects by identity');
235
+ });
236
+ vitest_1.describe.todo('on lists of lists', () => {
237
+ vitest_1.it.todo('rejects operations by value or identity');
238
+ });
239
+ (0, vitest_1.it)('should work for complex nested arrays and objects', () => {
240
+ const from = {
241
+ foo: {
242
+ bar: [1, 2, 3],
243
+ },
244
+ baz: [
245
+ {
246
+ corge: true,
247
+ },
248
+ ],
249
+ };
250
+ (0, oids_js_1.assignOid)(from, 'test/a');
251
+ (0, oids_js_1.assignOid)(from.foo, 'test/a:1');
252
+ (0, oids_js_1.assignOid)(from.foo.bar, 'test/a:2');
253
+ (0, oids_js_1.assignOid)(from.baz, 'test/a:3');
254
+ (0, oids_js_1.assignOid)(from.baz[0], 'test/a:4');
255
+ const to = {
256
+ foo: {
257
+ bar: [1, 2],
258
+ bop: [0],
259
+ },
260
+ baz: [
261
+ {
262
+ corge: false,
263
+ },
264
+ {
265
+ corge: false,
266
+ },
267
+ ],
268
+ };
269
+ (0, oids_js_1.assignOid)(to, 'test/a');
270
+ (0, oids_js_1.assignOid)(to.foo, 'test/a:1');
271
+ (0, oids_js_1.assignOid)(to.foo.bar, 'test/a:2');
272
+ (0, oids_js_1.assignOid)(to.foo.bop, 'test/a:6');
273
+ (0, oids_js_1.assignOid)(to.baz, 'test/a:3');
274
+ (0, oids_js_1.assignOid)(to.baz[0], 'test/a:4');
275
+ (0, oids_js_1.assignOid)(to.baz[1], 'test/a:5');
276
+ (0, vitest_1.expect)((0, operation_js_1.diffToPatches)(from, to, createClock(), [])).toMatchInlineSnapshot(`
277
+ [
278
+ {
279
+ "data": {
280
+ "count": 1,
281
+ "index": 2,
282
+ "op": "list-delete",
283
+ },
284
+ "oid": "test/a:2",
285
+ "timestamp": "0",
286
+ },
287
+ {
288
+ "data": {
289
+ "op": "initialize",
290
+ "value": [
291
+ 0,
292
+ ],
293
+ },
294
+ "oid": "test/a:6",
295
+ "timestamp": "1",
296
+ },
297
+ {
298
+ "data": {
299
+ "name": "bop",
300
+ "op": "set",
301
+ "value": {
302
+ "@@type": "ref",
303
+ "id": "test/a:6",
304
+ },
305
+ },
306
+ "oid": "test/a:1",
307
+ "timestamp": "2",
308
+ },
309
+ {
310
+ "data": {
311
+ "name": "corge",
312
+ "op": "set",
313
+ "value": false,
314
+ },
315
+ "oid": "test/a:4",
316
+ "timestamp": "3",
317
+ },
318
+ {
319
+ "data": {
320
+ "op": "initialize",
321
+ "value": {
322
+ "corge": false,
323
+ },
324
+ },
325
+ "oid": "test/a:5",
326
+ "timestamp": "4",
327
+ },
328
+ {
329
+ "data": {
330
+ "name": 1,
331
+ "op": "set",
332
+ "value": {
333
+ "@@type": "ref",
334
+ "id": "test/a:5",
335
+ },
336
+ },
337
+ "oid": "test/a:3",
338
+ "timestamp": "5",
339
+ },
340
+ ]
341
+ `);
342
+ });
343
+ (0, vitest_1.it)('should try to merge unknown objects if specified to do so', () => {
344
+ const from = {
345
+ foo: {
346
+ bar: [1, 2, 3],
347
+ },
348
+ baz: [
349
+ {
350
+ corge: true,
351
+ },
352
+ ],
353
+ };
354
+ (0, oids_js_1.assignOid)(from, 'test/a');
355
+ (0, oids_js_1.assignOidsToAllSubObjects)(from, createClock());
356
+ const to = {
357
+ foo: {
358
+ bar: [1, 2],
359
+ bop: [0],
360
+ },
361
+ baz: [
362
+ {
363
+ corge: false,
364
+ },
365
+ {
366
+ corge: false,
367
+ },
368
+ ],
369
+ };
370
+ (0, vitest_1.expect)((0, operation_js_1.diffToPatches)(from, to, createClock(), [], createClock(5), [], {
371
+ mergeUnknownObjects: true,
372
+ })).toMatchInlineSnapshot(`
373
+ [
374
+ {
375
+ "data": {
376
+ "count": 1,
377
+ "index": 2,
378
+ "op": "list-delete",
379
+ },
380
+ "oid": "test/a.foo.bar:1",
381
+ "timestamp": "0",
382
+ },
383
+ {
384
+ "data": {
385
+ "op": "initialize",
386
+ "value": [
387
+ 0,
388
+ ],
389
+ },
390
+ "oid": "test/a.foo.bop:5",
391
+ "timestamp": "1",
392
+ },
393
+ {
394
+ "data": {
395
+ "name": "bop",
396
+ "op": "set",
397
+ "value": {
398
+ "@@type": "ref",
399
+ "id": "test/a.foo.bop:5",
400
+ },
401
+ },
402
+ "oid": "test/a.foo:0",
403
+ "timestamp": "2",
404
+ },
405
+ {
406
+ "data": {
407
+ "name": "corge",
408
+ "op": "set",
409
+ "value": false,
410
+ },
411
+ "oid": "test/a.baz.#:3",
412
+ "timestamp": "3",
413
+ },
414
+ {
415
+ "data": {
416
+ "op": "initialize",
417
+ "value": {
418
+ "corge": false,
419
+ },
420
+ },
421
+ "oid": "test/a.baz.#:6",
422
+ "timestamp": "4",
423
+ },
424
+ {
425
+ "data": {
426
+ "name": 1,
427
+ "op": "set",
428
+ "value": {
429
+ "@@type": "ref",
430
+ "id": "test/a.baz.#:6",
431
+ },
432
+ },
433
+ "oid": "test/a.baz:2",
434
+ "timestamp": "5",
435
+ },
436
+ ]
437
+ `);
438
+ });
439
+ (0, vitest_1.it)('should not diff file refs', () => {
440
+ const from = {
441
+ foo: {
442
+ file: (0, files_js_1.createFileRef)('abc123'),
443
+ },
444
+ bar: [(0, files_js_1.createFileRef)('def456'), (0, files_js_1.createFileRef)('ghi789')],
445
+ };
446
+ (0, oids_js_1.assignOid)(from, 'test/a');
447
+ (0, oids_js_1.assignOidsToAllSubObjects)(from, createClock());
448
+ const to = {
449
+ foo: {
450
+ file: (0, files_js_1.createFileRef)('abc456'),
451
+ },
452
+ bar: [(0, files_js_1.createFileRef)('def456')],
453
+ };
454
+ (0, vitest_1.expect)((0, operation_js_1.diffToPatches)(from, to, createClock(), [], createClock(5), [], {
455
+ mergeUnknownObjects: true,
456
+ })).toMatchInlineSnapshot(`
457
+ [
458
+ {
459
+ "data": {
460
+ "name": "file",
461
+ "op": "set",
462
+ "value": {
463
+ "@@type": "file",
464
+ "id": "abc456",
465
+ },
466
+ },
467
+ "oid": "test/a.foo:0",
468
+ "timestamp": "0",
469
+ },
470
+ {
471
+ "data": {
472
+ "count": 1,
473
+ "index": 1,
474
+ "op": "list-delete",
475
+ },
476
+ "oid": "test/a.bar:1",
477
+ "timestamp": "1",
478
+ },
479
+ ]
480
+ `);
481
+ });
482
+ });
483
+ (0, vitest_1.describe)('substituting refs with objects', () => {
484
+ (0, vitest_1.it)('does nothing when no refs exist', () => {
485
+ const root = {
486
+ foo: 'bar',
487
+ };
488
+ (0, oids_js_1.assignOid)(root, 'test/a');
489
+ const substituted = (0, operation_js_1.substituteRefsWithObjects)(root, new Map());
490
+ (0, vitest_1.expect)(root).toEqual((0, oids_js_1.assignOid)({
491
+ foo: 'bar',
492
+ }, 'test/a'));
493
+ (0, vitest_1.expect)(substituted).toEqual([]);
494
+ });
495
+ (0, vitest_1.it)('inserts top level objects with oids', () => {
496
+ const root = {
497
+ foo: {
498
+ '@@type': 'ref',
499
+ id: 'test/1:a',
500
+ },
501
+ qux: 1,
502
+ };
503
+ (0, oids_js_1.assignOid)(root, 'test/1');
504
+ const substituted = (0, operation_js_1.substituteRefsWithObjects)(root, new Map([['test/1:a', { foo: 'bar' }]]));
505
+ (0, vitest_1.expect)(root).toEqual((0, oids_js_1.assignOid)({
506
+ foo: (0, oids_js_1.assignOid)({
507
+ foo: 'bar',
508
+ }, 'test/1:a'),
509
+ qux: 1,
510
+ }, 'test/1'));
511
+ (0, vitest_1.expect)(substituted).toEqual(['test/1:a']);
512
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root)).toEqual('test/1');
513
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root.foo)).toEqual('test/1:a');
514
+ });
515
+ (0, vitest_1.it)('inserts nested objects with oids', () => {
516
+ const root = {
517
+ foo: {
518
+ '@@type': 'ref',
519
+ id: 'test/1:a',
520
+ },
521
+ };
522
+ (0, oids_js_1.assignOid)(root, 'test/1');
523
+ const substituted = (0, operation_js_1.substituteRefsWithObjects)(root, new Map([
524
+ [
525
+ 'test/1:a',
526
+ {
527
+ foo: 'bar',
528
+ baz: {
529
+ '@@type': 'ref',
530
+ id: 'test/1:b',
531
+ },
532
+ },
533
+ ],
534
+ [
535
+ 'test/1:b',
536
+ {
537
+ qux: 'corge',
538
+ },
539
+ ],
540
+ ]));
541
+ (0, vitest_1.expect)(root).toEqual((0, oids_js_1.assignOid)({
542
+ foo: (0, oids_js_1.assignOid)({
543
+ foo: 'bar',
544
+ baz: (0, oids_js_1.assignOid)({
545
+ qux: 'corge',
546
+ }, 'test/1:b'),
547
+ }, 'test/1:a'),
548
+ }, 'test/1'));
549
+ (0, vitest_1.expect)(substituted).toEqual(['test/1:a', 'test/1:b']);
550
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root)).toEqual('test/1');
551
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root.foo)).toEqual('test/1:a');
552
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root.foo.baz)).toEqual('test/1:b');
553
+ });
554
+ (0, vitest_1.it)('substitutes arrays of objects', () => {
555
+ const root = {
556
+ foo: {
557
+ '@@type': 'ref',
558
+ id: 'test/1:c',
559
+ },
560
+ };
561
+ (0, oids_js_1.assignOid)(root, 'test/1');
562
+ const substituted = (0, operation_js_1.substituteRefsWithObjects)(root, new Map([
563
+ [
564
+ 'test/1:c',
565
+ [
566
+ {
567
+ '@@type': 'ref',
568
+ id: 'test/1:a',
569
+ },
570
+ {
571
+ '@@type': 'ref',
572
+ id: 'test/1:b',
573
+ },
574
+ ],
575
+ ],
576
+ [
577
+ 'test/1:a',
578
+ {
579
+ foo: 'bar',
580
+ },
581
+ ],
582
+ [
583
+ 'test/1:b',
584
+ {
585
+ qux: 'corge',
586
+ },
587
+ ],
588
+ ]));
589
+ (0, vitest_1.expect)(root).toEqual({
590
+ foo: (0, oids_js_1.assignOid)([
591
+ (0, oids_js_1.assignOid)({
592
+ foo: 'bar',
593
+ }, 'test/1:a'),
594
+ (0, oids_js_1.assignOid)({
595
+ qux: 'corge',
596
+ }, 'test/1:b'),
597
+ ], 'test/1:c'),
598
+ });
599
+ (0, vitest_1.expect)(substituted).toEqual(['test/1:c', 'test/1:a', 'test/1:b']);
600
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root)).toEqual('test/1');
601
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root.foo)).toEqual('test/1:c');
602
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root.foo[0])).toEqual('test/1:a');
603
+ (0, vitest_1.expect)((0, oids_js_1.getOid)(root.foo[1])).toEqual('test/1:b');
604
+ });
605
+ vitest_1.it.todo('substitutes arrays of arrays of objects');
606
+ });
607
+ (0, vitest_1.describe)('creating patches from initial state', () => {
608
+ (0, vitest_1.it)('adds oids to all sub-objects', async () => {
609
+ let i = 0;
610
+ function createSubId() {
611
+ return (i++).toString();
612
+ }
613
+ const result = (0, operation_js_1.initialToPatches)({
614
+ foo: {
615
+ bar: 'baz',
616
+ },
617
+ qux: [
618
+ {
619
+ corge: 'grault',
620
+ },
621
+ {
622
+ bin: {
623
+ oof: 1,
624
+ },
625
+ },
626
+ ],
627
+ }, 'test/a', createClock(), createSubId);
628
+ /**
629
+ * Patches should not include assigned OID property
630
+ */
631
+ (0, vitest_1.expect)(result).toMatchInlineSnapshot(`
632
+ [
633
+ {
634
+ "data": {
635
+ "op": "initialize",
636
+ "value": {
637
+ "bar": "baz",
638
+ },
639
+ },
640
+ "oid": "test/a.foo:0",
641
+ "timestamp": "0",
642
+ },
643
+ {
644
+ "data": {
645
+ "op": "initialize",
646
+ "value": {
647
+ "corge": "grault",
648
+ },
649
+ },
650
+ "oid": "test/a.qux.#:2",
651
+ "timestamp": "1",
652
+ },
653
+ {
654
+ "data": {
655
+ "op": "initialize",
656
+ "value": {
657
+ "oof": 1,
658
+ },
659
+ },
660
+ "oid": "test/a.qux.#.bin:4",
661
+ "timestamp": "2",
662
+ },
663
+ {
664
+ "data": {
665
+ "op": "initialize",
666
+ "value": {
667
+ "bin": {
668
+ "@@type": "ref",
669
+ "id": "test/a.qux.#.bin:4",
670
+ },
671
+ },
672
+ },
673
+ "oid": "test/a.qux.#:3",
674
+ "timestamp": "3",
675
+ },
676
+ {
677
+ "data": {
678
+ "op": "initialize",
679
+ "value": [
680
+ {
681
+ "@@type": "ref",
682
+ "id": "test/a.qux.#:2",
683
+ },
684
+ {
685
+ "@@type": "ref",
686
+ "id": "test/a.qux.#:3",
687
+ },
688
+ ],
689
+ },
690
+ "oid": "test/a.qux:1",
691
+ "timestamp": "4",
692
+ },
693
+ {
694
+ "data": {
695
+ "op": "initialize",
696
+ "value": {
697
+ "foo": {
698
+ "@@type": "ref",
699
+ "id": "test/a.foo:0",
700
+ },
701
+ "qux": {
702
+ "@@type": "ref",
703
+ "id": "test/a.qux:1",
704
+ },
705
+ },
706
+ },
707
+ "oid": "test/a",
708
+ "timestamp": "5",
709
+ },
710
+ ]
711
+ `);
712
+ });
713
+ });
714
+ (0, vitest_1.describe)('applying individual operations', () => {
715
+ (0, vitest_1.it)('applies a list-remove of only the last instance', () => {
716
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)(['a', 'b', 'c', 'a', 'b'], {
717
+ op: 'list-remove',
718
+ value: 'a',
719
+ only: 'last',
720
+ })).toEqual(['a', 'b', 'c', 'b']);
721
+ });
722
+ (0, vitest_1.it)('applies a list-remove of only the first instance', () => {
723
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)(['a', 'b', 'c', 'a', 'b'], {
724
+ op: 'list-remove',
725
+ value: 'a',
726
+ only: 'first',
727
+ })).toEqual(['b', 'c', 'a', 'b']);
728
+ });
729
+ (0, vitest_1.it)('applies a list-remove of all instances', () => {
730
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)(['a', 'b', 'c', 'a', 'b'], {
731
+ op: 'list-remove',
732
+ value: 'a',
733
+ })).toEqual(['b', 'c', 'b']);
734
+ });
735
+ (0, vitest_1.it)('applies a list-remove of an object ref', () => {
736
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)([
737
+ (0, oids_js_1.createRef)('a'),
738
+ (0, oids_js_1.createRef)('b'),
739
+ (0, oids_js_1.createRef)('c'),
740
+ (0, oids_js_1.createRef)('a'),
741
+ (0, oids_js_1.createRef)('b'),
742
+ ], {
743
+ op: 'list-remove',
744
+ value: (0, oids_js_1.createRef)('a'),
745
+ only: 'last',
746
+ })).toEqual([(0, oids_js_1.createRef)('a'), (0, oids_js_1.createRef)('b'), (0, oids_js_1.createRef)('c'), (0, oids_js_1.createRef)('b')]);
747
+ });
748
+ (0, vitest_1.it)('applies a list-add of a nonexistent item', () => {
749
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)(['a', 'b', 'c'], {
750
+ op: 'list-add',
751
+ value: 'd',
752
+ })).toEqual(['a', 'b', 'c', 'd']);
753
+ });
754
+ (0, vitest_1.it)('does not apply a list-add if the item is already present', () => {
755
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)(['a', 'b', 'c'], {
756
+ op: 'list-add',
757
+ value: 'b',
758
+ })).toEqual(['a', 'b', 'c']);
759
+ });
760
+ });
761
+ (0, vitest_1.describe)('collecting deleted refs during patch application', () => {
762
+ (0, vitest_1.it)('collects refs that are removed from a list', () => {
763
+ const refs = [];
764
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)([
765
+ (0, oids_js_1.createRef)('a'),
766
+ (0, oids_js_1.createRef)('b'),
767
+ (0, oids_js_1.createRef)('c'),
768
+ (0, oids_js_1.createRef)('d'),
769
+ (0, oids_js_1.createRef)('e'),
770
+ ], {
771
+ op: 'list-remove',
772
+ value: (0, oids_js_1.createRef)('c'),
773
+ }, refs)).toEqual([(0, oids_js_1.createRef)('a'), (0, oids_js_1.createRef)('b'), (0, oids_js_1.createRef)('d'), (0, oids_js_1.createRef)('e')]);
774
+ (0, vitest_1.expect)(refs).toEqual([(0, oids_js_1.createRef)('c')]);
775
+ });
776
+ (0, vitest_1.it)('collects a deleted ref field from an object', () => {
777
+ const refs = [];
778
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)({
779
+ a: (0, oids_js_1.createRef)('a'),
780
+ b: (0, oids_js_1.createRef)('b'),
781
+ c: (0, oids_js_1.createRef)('c'),
782
+ }, {
783
+ op: 'remove',
784
+ name: 'b',
785
+ }, refs)).toEqual({
786
+ a: (0, oids_js_1.createRef)('a'),
787
+ c: (0, oids_js_1.createRef)('c'),
788
+ });
789
+ (0, vitest_1.expect)(refs).toEqual([(0, oids_js_1.createRef)('b')]);
790
+ });
791
+ (0, vitest_1.it)('collects all refs in a deleted object', () => {
792
+ const refs = [];
793
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)({
794
+ a: (0, oids_js_1.createRef)('a'),
795
+ b: (0, oids_js_1.createRef)('b'),
796
+ c: (0, oids_js_1.createRef)('c'),
797
+ }, {
798
+ op: 'delete',
799
+ }, refs)).toEqual(undefined);
800
+ (0, vitest_1.expect)(refs).toEqual([(0, oids_js_1.createRef)('a'), (0, oids_js_1.createRef)('b'), (0, oids_js_1.createRef)('c')]);
801
+ });
802
+ (0, vitest_1.it)('collects all refs in a deleted list', () => {
803
+ const refs = [];
804
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)([(0, oids_js_1.createRef)('a'), (0, oids_js_1.createRef)('b'), (0, oids_js_1.createRef)('c')], {
805
+ op: 'delete',
806
+ }, refs)).toEqual(undefined);
807
+ (0, vitest_1.expect)(refs).toEqual([(0, oids_js_1.createRef)('a'), (0, oids_js_1.createRef)('b'), (0, oids_js_1.createRef)('c')]);
808
+ });
809
+ (0, vitest_1.it)('collects a ref in a replaced field', () => {
810
+ const refs = [];
811
+ (0, vitest_1.expect)((0, operation_js_1.applyPatch)({
812
+ a: (0, oids_js_1.createRef)('a'),
813
+ b: (0, oids_js_1.createRef)('b'),
814
+ c: (0, oids_js_1.createRef)('c'),
815
+ }, {
816
+ op: 'set',
817
+ name: 'b',
818
+ value: (0, oids_js_1.createRef)('d'),
819
+ }, refs)).toEqual({
820
+ a: (0, oids_js_1.createRef)('a'),
821
+ b: (0, oids_js_1.createRef)('d'),
822
+ c: (0, oids_js_1.createRef)('c'),
823
+ });
824
+ (0, vitest_1.expect)(refs).toEqual([(0, oids_js_1.createRef)('b')]);
825
+ });
826
+ });
827
+ //# sourceMappingURL=operation.test.js.map