@verdant-web/common 1.15.3-next.0 → 1.15.4

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 (154) hide show
  1. package/dist/cjs/EventSubscriber.d.ts +17 -17
  2. package/dist/cjs/EventSubscriber.js +66 -66
  3. package/dist/cjs/baseline.d.ts +5 -5
  4. package/dist/cjs/baseline.js +2 -2
  5. package/dist/cjs/batching.d.ts +42 -42
  6. package/dist/cjs/batching.js +91 -91
  7. package/dist/cjs/files.d.ts +19 -19
  8. package/dist/cjs/files.js +18 -18
  9. package/dist/cjs/index.d.ts +19 -19
  10. package/dist/cjs/index.js +41 -41
  11. package/dist/cjs/indexes.d.ts +17 -17
  12. package/dist/cjs/indexes.js +142 -142
  13. package/dist/cjs/indexes.test.d.ts +1 -1
  14. package/dist/cjs/indexes.test.js +127 -127
  15. package/dist/cjs/migration.d.ts +172 -172
  16. package/dist/cjs/migration.js +301 -301
  17. package/dist/cjs/oids.d.ts +100 -100
  18. package/dist/cjs/oids.js +461 -457
  19. package/dist/cjs/oids.js.map +1 -1
  20. package/dist/cjs/oids.test.d.ts +1 -1
  21. package/dist/cjs/oids.test.js +348 -348
  22. package/dist/cjs/operation.d.ts +139 -139
  23. package/dist/cjs/operation.js +545 -545
  24. package/dist/cjs/operation.test.d.ts +1 -1
  25. package/dist/cjs/operation.test.js +529 -529
  26. package/dist/cjs/patch.d.ts +26 -26
  27. package/dist/cjs/patch.js +226 -226
  28. package/dist/cjs/presence.d.ts +27 -27
  29. package/dist/cjs/presence.js +2 -2
  30. package/dist/cjs/protocol.d.ts +145 -145
  31. package/dist/cjs/protocol.js +3 -3
  32. package/dist/cjs/refs.d.ts +7 -7
  33. package/dist/cjs/refs.js +29 -29
  34. package/dist/cjs/replica.d.ts +28 -28
  35. package/dist/cjs/replica.js +28 -28
  36. package/dist/cjs/schema/defaults.test.d.ts +1 -1
  37. package/dist/cjs/schema/defaults.test.js +20 -20
  38. package/dist/cjs/schema/fields.d.ts +9 -9
  39. package/dist/cjs/schema/fields.js +144 -144
  40. package/dist/cjs/schema/index.d.ts +8 -8
  41. package/dist/cjs/schema/index.js +51 -51
  42. package/dist/cjs/schema/indexFilters.d.ts +6 -6
  43. package/dist/cjs/schema/indexFilters.js +30 -30
  44. package/dist/cjs/schema/types/collection.d.ts +23 -23
  45. package/dist/cjs/schema/types/collection.js +2 -2
  46. package/dist/cjs/schema/types/compounds.d.ts +11 -11
  47. package/dist/cjs/schema/types/compounds.js +2 -2
  48. package/dist/cjs/schema/types/fields.d.ts +75 -75
  49. package/dist/cjs/schema/types/fields.js +2 -2
  50. package/dist/cjs/schema/types/filters.d.ts +29 -29
  51. package/dist/cjs/schema/types/filters.js +2 -2
  52. package/dist/cjs/schema/types/shapes.d.ts +21 -21
  53. package/dist/cjs/schema/types/shapes.js +2 -2
  54. package/dist/cjs/schema/types/synthetics.d.ts +37 -37
  55. package/dist/cjs/schema/types/synthetics.js +2 -2
  56. package/dist/cjs/schema/types.d.ts +18 -18
  57. package/dist/cjs/schema/types.js +22 -22
  58. package/dist/cjs/schema/validation.d.ts +3 -3
  59. package/dist/cjs/schema/validation.js +86 -86
  60. package/dist/cjs/timestamp.d.ts +50 -50
  61. package/dist/cjs/timestamp.js +251 -251
  62. package/dist/cjs/timestamp.test.d.ts +1 -1
  63. package/dist/cjs/timestamp.test.js +104 -104
  64. package/dist/cjs/undo.d.ts +3 -3
  65. package/dist/cjs/undo.js +198 -198
  66. package/dist/cjs/utils.d.ts +20 -20
  67. package/dist/cjs/utils.js +145 -145
  68. package/dist/cjs/utils.test.d.ts +1 -1
  69. package/dist/cjs/utils.test.js +36 -36
  70. package/dist/esm/EventSubscriber.d.ts +17 -17
  71. package/dist/esm/EventSubscriber.js +62 -62
  72. package/dist/esm/baseline.d.ts +5 -5
  73. package/dist/esm/baseline.js +1 -1
  74. package/dist/esm/batching.d.ts +42 -42
  75. package/dist/esm/batching.js +86 -86
  76. package/dist/esm/files.d.ts +19 -19
  77. package/dist/esm/files.js +12 -12
  78. package/dist/esm/index.d.ts +19 -19
  79. package/dist/esm/index.js +16 -16
  80. package/dist/esm/indexes.d.ts +17 -17
  81. package/dist/esm/indexes.js +130 -130
  82. package/dist/esm/indexes.test.d.ts +1 -1
  83. package/dist/esm/indexes.test.js +125 -125
  84. package/dist/esm/migration.d.ts +172 -172
  85. package/dist/esm/migration.js +294 -294
  86. package/dist/esm/oids.d.ts +100 -100
  87. package/dist/esm/oids.js +426 -422
  88. package/dist/esm/oids.js.map +1 -1
  89. package/dist/esm/oids.test.d.ts +1 -1
  90. package/dist/esm/oids.test.js +346 -346
  91. package/dist/esm/operation.d.ts +139 -139
  92. package/dist/esm/operation.js +530 -530
  93. package/dist/esm/operation.test.d.ts +1 -1
  94. package/dist/esm/operation.test.js +527 -527
  95. package/dist/esm/patch.d.ts +26 -26
  96. package/dist/esm/patch.js +222 -222
  97. package/dist/esm/presence.d.ts +27 -27
  98. package/dist/esm/presence.js +1 -1
  99. package/dist/esm/protocol.d.ts +145 -145
  100. package/dist/esm/protocol.js +2 -2
  101. package/dist/esm/refs.d.ts +7 -7
  102. package/dist/esm/refs.js +22 -22
  103. package/dist/esm/replica.d.ts +28 -28
  104. package/dist/esm/replica.js +25 -25
  105. package/dist/esm/schema/defaults.test.d.ts +1 -1
  106. package/dist/esm/schema/defaults.test.js +18 -18
  107. package/dist/esm/schema/fields.d.ts +9 -9
  108. package/dist/esm/schema/fields.js +133 -133
  109. package/dist/esm/schema/index.d.ts +8 -8
  110. package/dist/esm/schema/index.js +32 -32
  111. package/dist/esm/schema/indexFilters.d.ts +6 -6
  112. package/dist/esm/schema/indexFilters.js +22 -22
  113. package/dist/esm/schema/types/collection.d.ts +23 -23
  114. package/dist/esm/schema/types/collection.js +1 -1
  115. package/dist/esm/schema/types/compounds.d.ts +11 -11
  116. package/dist/esm/schema/types/compounds.js +1 -1
  117. package/dist/esm/schema/types/fields.d.ts +75 -75
  118. package/dist/esm/schema/types/fields.js +1 -1
  119. package/dist/esm/schema/types/filters.d.ts +29 -29
  120. package/dist/esm/schema/types/filters.js +1 -1
  121. package/dist/esm/schema/types/shapes.d.ts +21 -21
  122. package/dist/esm/schema/types/shapes.js +1 -1
  123. package/dist/esm/schema/types/synthetics.d.ts +37 -37
  124. package/dist/esm/schema/types/synthetics.js +1 -1
  125. package/dist/esm/schema/types.d.ts +18 -18
  126. package/dist/esm/schema/types.js +6 -6
  127. package/dist/esm/schema/validation.d.ts +3 -3
  128. package/dist/esm/schema/validation.js +81 -81
  129. package/dist/esm/timestamp.d.ts +50 -50
  130. package/dist/esm/timestamp.js +234 -234
  131. package/dist/esm/timestamp.test.d.ts +1 -1
  132. package/dist/esm/timestamp.test.js +102 -102
  133. package/dist/esm/undo.d.ts +3 -3
  134. package/dist/esm/undo.js +194 -194
  135. package/dist/esm/utils.d.ts +20 -20
  136. package/dist/esm/utils.js +127 -127
  137. package/dist/esm/utils.test.d.ts +1 -1
  138. package/dist/esm/utils.test.js +34 -34
  139. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  140. package/dist/tsconfig.tsbuildinfo +1 -1
  141. package/package.json +1 -1
  142. package/src/oids.ts +5 -1
  143. package/dist/cjs/files.test.d.ts +0 -1
  144. package/dist/cjs/files.test.js +0 -81
  145. package/dist/cjs/files.test.js.map +0 -1
  146. package/dist/cjs/schema/defaults.d.ts +0 -4
  147. package/dist/cjs/schema/defaults.js +0 -72
  148. package/dist/cjs/schema/defaults.js.map +0 -1
  149. package/dist/esm/files.test.d.ts +0 -1
  150. package/dist/esm/files.test.js +0 -79
  151. package/dist/esm/files.test.js.map +0 -1
  152. package/dist/esm/schema/defaults.d.ts +0 -4
  153. package/dist/esm/schema/defaults.js +0 -66
  154. package/dist/esm/schema/defaults.js.map +0 -1
@@ -1,295 +1,295 @@
1
- import { stableStringify, addFieldDefaults, removeExtraProperties, assert, assignOid, getOid, hasDefault, } from './index.js';
2
- const emptySchema = {
3
- version: 0,
4
- collections: {},
5
- };
6
- export function migrate(oldSchemaOrNewSchema, newSchemaOrProcedure, procedureIfTwoSchemas) {
7
- const isProcedureSecondArgument = typeof newSchemaOrProcedure === 'function';
8
- const oldSchema = isProcedureSecondArgument
9
- ? emptySchema
10
- : oldSchemaOrNewSchema;
11
- const newSchema = isProcedureSecondArgument
12
- ? oldSchemaOrNewSchema
13
- : newSchemaOrProcedure;
14
- const procedure = isProcedureSecondArgument
15
- ? newSchemaOrProcedure
16
- : procedureIfTwoSchemas;
17
- // diff to determine changed collections
18
- const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
19
- stableStringify(oldSchema.collections[key]) !==
20
- stableStringify(newSchema.collections[key]));
21
- const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
22
- const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
23
- // collections which added one or more field defaults
24
- const autoMigratedCollections = new Set();
25
- for (const collection of changedCollections) {
26
- const oldFields = oldSchema.collections[collection].fields;
27
- const newFields = newSchema.collections[collection].fields;
28
- // a new default was added - we can auto-migrate it
29
- if (Object.keys(newFields).some((key) => { var _a, _b; return !((_a = oldFields[key]) === null || _a === void 0 ? void 0 : _a.default) && ((_b = newFields[key]) === null || _b === void 0 ? void 0 : _b.default); })) {
30
- autoMigratedCollections.add(collection);
31
- }
32
- // a field was removed - we can auto-migrate it
33
- if (Object.keys(oldFields).some((key) => !newFields[key])) {
34
- autoMigratedCollections.add(collection);
35
- }
36
- }
37
- const addedIndexes = {};
38
- const removedIndexes = {};
39
- for (const changed of [...changedCollections, ...addedCollections]) {
40
- const oldIndexes = getIndexes(oldSchema.collections[changed]);
41
- const newIndexes = getIndexes(newSchema.collections[changed]);
42
- const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
43
- const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
44
- if (added.length > 0) {
45
- addedIndexes[changed] = added;
46
- // FIXME: don't o(n^2) this
47
- if (changedCollections.includes(changed)) {
48
- autoMigratedCollections.add(changed);
49
- }
50
- }
51
- if (removed.length > 0) {
52
- removedIndexes[changed] = removed;
53
- // FIXME: don't o(n^2) this
54
- if (changedCollections.includes(changed)) {
55
- autoMigratedCollections.add(changed);
56
- }
57
- }
58
- }
59
- const withDefaults = (collectionName, val) => {
60
- return addFieldDefaults(newSchema.collections[collectionName], val);
61
- };
62
- const autoMigration = (collectionName) => (val) => {
63
- const collection = newSchema.collections[collectionName];
64
- return addFieldDefaults(collection, removeExtraProperties(collection, val));
65
- };
66
- return {
67
- version: newSchema.version,
68
- migrate: async (engine) => {
69
- const migratedCollections = [];
70
- await procedure({
71
- migrate: async (collection, strategy) => {
72
- const auto = autoMigration(collection);
73
- const wrapped = async (val) => {
74
- const baseValue = await strategy(val);
75
- // assign OID from original value in case user's strategy
76
- // involves cloning
77
- assignOid(baseValue, getOid(val));
78
- const result = auto(baseValue);
79
- return result;
80
- };
81
- // @ts-ignore
82
- await engine.migrate(collection, wrapped);
83
- migratedCollections.push(collection);
84
- // since the user migrated this one and we wrap their
85
- // strategy with auto-migration, we can remove it from
86
- // the auto-migration list
87
- autoMigratedCollections.delete(collection);
88
- },
89
- identity: (val) => val,
90
- withDefaults,
91
- info: {
92
- changedCollections,
93
- addedCollections,
94
- removedCollections,
95
- },
96
- queries: engine.queries,
97
- mutations: engine.mutations,
98
- });
99
- // mandatory migration of fields which had defaults added or
100
- // fields removed but weren't migrated by the user
101
- if (newSchema.version > 1) {
102
- engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
103
- for (const name of autoMigratedCollections) {
104
- await engine.migrate(name, autoMigration(name));
105
- migratedCollections.push(name);
106
- }
107
- const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
108
- if (unmigrated.length > 0) {
109
- // TODO: does this deserve a full-on error?
110
- console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
111
- }
112
- }
113
- },
114
- removedCollections,
115
- addedIndexes,
116
- removedIndexes,
117
- allCollections: Object.keys(newSchema.collections),
118
- changedCollections,
119
- addedCollections,
120
- oldCollections: Object.keys(oldSchema.collections),
121
- oldSchema,
122
- newSchema,
123
- };
124
- }
125
- export function migrationRange(from, to) {
126
- return [...Array(to - from).keys()].map((i) => 1 + i + from);
127
- }
128
- function getIndexes(collection) {
129
- if (!collection)
130
- return [];
131
- return [
132
- ...Object.keys(collection.indexes || {}).map((key) => ({
133
- name: key,
134
- multiEntry: ['array', 'string[]', 'number[]', 'boolean[]'].includes(collection.indexes[key].type),
135
- synthetic: true,
136
- compound: false,
137
- })),
138
- ...Object.keys(collection.compounds || {}).map((key) => ({
139
- name: key,
140
- multiEntry: collection.compounds[key].of.some((fieldName) => (collection.fields[fieldName] || collection.indexes[fieldName])
141
- .type === 'array'),
142
- synthetic: false,
143
- compound: true,
144
- })),
145
- ];
146
- }
147
- export function createDefaultMigration(schema, newSchema) {
148
- let oldSchema = newSchema
149
- ? schema
150
- : {
151
- version: 0,
152
- collections: {},
153
- };
154
- return migrate(oldSchema, newSchema || schema, async ({ migrate, info }) => {
155
- if ((newSchema || schema).version === 1)
156
- return;
157
- for (const collection of info.changedCollections) {
158
- // @ts-ignore indefinite type resolution
159
- await migrate(collection, (old) => old);
160
- }
161
- });
162
- }
163
- export function createMigration(maybeOldSchema, maybeNewSchemaOrProcedure, maybeProcedure) {
164
- const isProcedureSecondArgument = typeof maybeNewSchemaOrProcedure === 'function' ||
165
- maybeNewSchemaOrProcedure === undefined;
166
- const oldSchema = isProcedureSecondArgument ? emptySchema : maybeOldSchema;
167
- const newSchema = isProcedureSecondArgument
168
- ? maybeOldSchema
169
- : maybeNewSchemaOrProcedure;
170
- const procedure = isProcedureSecondArgument
171
- ? maybeNewSchemaOrProcedure
172
- : maybeProcedure;
173
- assert(oldSchema, 'Invalid arguments to createMigration');
174
- assert(newSchema, 'Invalid arguments to createMigration');
175
- const { changedCollections, addedCollections, removedCollections, addedIndexes, removedIndexes, autoMigratedCollections, autoMigration, } = getMigrationInfo(oldSchema, newSchema);
176
- return {
177
- version: newSchema.version,
178
- migrate: async (engine) => {
179
- const migratedCollections = [];
180
- const migrate = async (collection, strategy) => {
181
- const auto = autoMigration(collection);
182
- const wrapped = async (val) => {
183
- const baseValue = await strategy(val);
184
- // assign OID from original value in case user's strategy
185
- // involves cloning
186
- assignOid(baseValue, getOid(val));
187
- const result = auto(baseValue);
188
- return result;
189
- };
190
- // @ts-ignore
191
- await engine.migrate(collection, wrapped);
192
- migratedCollections.push(collection);
193
- // since the user migrated this one and we wrap their
194
- // strategy with auto-migration, we can remove it from
195
- // the auto-migration list
196
- autoMigratedCollections.delete(collection);
197
- };
198
- await (procedure === null || procedure === void 0 ? void 0 : procedure({
199
- migrate,
200
- info: {
201
- changedCollections,
202
- addedCollections,
203
- removedCollections,
204
- },
205
- queries: engine.queries,
206
- mutations: engine.mutations,
207
- }));
208
- // mandatory migration of fields which had defaults added or
209
- // fields removed but weren't migrated by the user
210
- if (newSchema.version > 1) {
211
- engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
212
- for (const name of autoMigratedCollections) {
213
- await engine.migrate(name, autoMigration(name));
214
- migratedCollections.push(name);
215
- }
216
- const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
217
- if (unmigrated.length > 0) {
218
- // TODO: does this deserve a full-on error?
219
- console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
220
- }
221
- }
222
- },
223
- removedCollections,
224
- addedIndexes,
225
- removedIndexes,
226
- allCollections: Object.keys(newSchema.collections),
227
- changedCollections,
228
- addedCollections,
229
- oldCollections: Object.keys(oldSchema.collections),
230
- oldSchema,
231
- newSchema,
232
- };
233
- }
234
- // common tools
235
- function getMigrationInfo(oldSchema, newSchema) {
236
- const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
237
- stableStringify(oldSchema.collections[key]) !==
238
- stableStringify(newSchema.collections[key]));
239
- const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
240
- const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
241
- // collections which added one or more field defaults
242
- const autoMigratedCollections = new Set();
243
- for (const collection of changedCollections) {
244
- const oldFields = oldSchema.collections[collection].fields;
245
- const newFields = newSchema.collections[collection].fields;
246
- // a new default was added - we can auto-migrate it
247
- if (Object.keys(newFields).some((key) => !hasDefault(oldFields[key]) && hasDefault(newFields[key]))) {
248
- autoMigratedCollections.add(collection);
249
- }
250
- // a field was removed - we can auto-migrate it
251
- if (Object.keys(oldFields).some((key) => !newFields[key])) {
252
- autoMigratedCollections.add(collection);
253
- }
254
- }
255
- const addedIndexes = {};
256
- const removedIndexes = {};
257
- for (const changed of [...changedCollections, ...addedCollections]) {
258
- const oldIndexes = getIndexes(oldSchema.collections[changed]);
259
- const newIndexes = getIndexes(newSchema.collections[changed]);
260
- const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
261
- const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
262
- if (added.length > 0) {
263
- addedIndexes[changed] = added;
264
- // FIXME: don't o(n^2) this
265
- if (changedCollections.includes(changed)) {
266
- autoMigratedCollections.add(changed);
267
- }
268
- }
269
- if (removed.length > 0) {
270
- removedIndexes[changed] = removed;
271
- // FIXME: don't o(n^2) this
272
- if (changedCollections.includes(changed)) {
273
- autoMigratedCollections.add(changed);
274
- }
275
- }
276
- }
277
- const withDefaults = (collectionName, val) => {
278
- return addFieldDefaults(newSchema.collections[collectionName], val);
279
- };
280
- const autoMigration = (collectionName) => (val) => {
281
- const collection = newSchema.collections[collectionName];
282
- return addFieldDefaults(collection, removeExtraProperties(collection, val));
283
- };
284
- return {
285
- changedCollections,
286
- addedCollections,
287
- removedCollections,
288
- addedIndexes,
289
- removedIndexes,
290
- autoMigratedCollections,
291
- withDefaults,
292
- autoMigration,
293
- };
294
- }
1
+ import { stableStringify, addFieldDefaults, removeExtraProperties, assert, assignOid, getOid, hasDefault, } from './index.js';
2
+ const emptySchema = {
3
+ version: 0,
4
+ collections: {},
5
+ };
6
+ export function migrate(oldSchemaOrNewSchema, newSchemaOrProcedure, procedureIfTwoSchemas) {
7
+ const isProcedureSecondArgument = typeof newSchemaOrProcedure === 'function';
8
+ const oldSchema = isProcedureSecondArgument
9
+ ? emptySchema
10
+ : oldSchemaOrNewSchema;
11
+ const newSchema = isProcedureSecondArgument
12
+ ? oldSchemaOrNewSchema
13
+ : newSchemaOrProcedure;
14
+ const procedure = isProcedureSecondArgument
15
+ ? newSchemaOrProcedure
16
+ : procedureIfTwoSchemas;
17
+ // diff to determine changed collections
18
+ const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
19
+ stableStringify(oldSchema.collections[key]) !==
20
+ stableStringify(newSchema.collections[key]));
21
+ const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
22
+ const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
23
+ // collections which added one or more field defaults
24
+ const autoMigratedCollections = new Set();
25
+ for (const collection of changedCollections) {
26
+ const oldFields = oldSchema.collections[collection].fields;
27
+ const newFields = newSchema.collections[collection].fields;
28
+ // a new default was added - we can auto-migrate it
29
+ if (Object.keys(newFields).some((key) => { var _a, _b; return !((_a = oldFields[key]) === null || _a === void 0 ? void 0 : _a.default) && ((_b = newFields[key]) === null || _b === void 0 ? void 0 : _b.default); })) {
30
+ autoMigratedCollections.add(collection);
31
+ }
32
+ // a field was removed - we can auto-migrate it
33
+ if (Object.keys(oldFields).some((key) => !newFields[key])) {
34
+ autoMigratedCollections.add(collection);
35
+ }
36
+ }
37
+ const addedIndexes = {};
38
+ const removedIndexes = {};
39
+ for (const changed of [...changedCollections, ...addedCollections]) {
40
+ const oldIndexes = getIndexes(oldSchema.collections[changed]);
41
+ const newIndexes = getIndexes(newSchema.collections[changed]);
42
+ const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
43
+ const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
44
+ if (added.length > 0) {
45
+ addedIndexes[changed] = added;
46
+ // FIXME: don't o(n^2) this
47
+ if (changedCollections.includes(changed)) {
48
+ autoMigratedCollections.add(changed);
49
+ }
50
+ }
51
+ if (removed.length > 0) {
52
+ removedIndexes[changed] = removed;
53
+ // FIXME: don't o(n^2) this
54
+ if (changedCollections.includes(changed)) {
55
+ autoMigratedCollections.add(changed);
56
+ }
57
+ }
58
+ }
59
+ const withDefaults = (collectionName, val) => {
60
+ return addFieldDefaults(newSchema.collections[collectionName], val);
61
+ };
62
+ const autoMigration = (collectionName) => (val) => {
63
+ const collection = newSchema.collections[collectionName];
64
+ return addFieldDefaults(collection, removeExtraProperties(collection, val));
65
+ };
66
+ return {
67
+ version: newSchema.version,
68
+ migrate: async (engine) => {
69
+ const migratedCollections = [];
70
+ await procedure({
71
+ migrate: async (collection, strategy) => {
72
+ const auto = autoMigration(collection);
73
+ const wrapped = async (val) => {
74
+ const baseValue = await strategy(val);
75
+ // assign OID from original value in case user's strategy
76
+ // involves cloning
77
+ assignOid(baseValue, getOid(val));
78
+ const result = auto(baseValue);
79
+ return result;
80
+ };
81
+ // @ts-ignore
82
+ await engine.migrate(collection, wrapped);
83
+ migratedCollections.push(collection);
84
+ // since the user migrated this one and we wrap their
85
+ // strategy with auto-migration, we can remove it from
86
+ // the auto-migration list
87
+ autoMigratedCollections.delete(collection);
88
+ },
89
+ identity: (val) => val,
90
+ withDefaults,
91
+ info: {
92
+ changedCollections,
93
+ addedCollections,
94
+ removedCollections,
95
+ },
96
+ queries: engine.queries,
97
+ mutations: engine.mutations,
98
+ });
99
+ // mandatory migration of fields which had defaults added or
100
+ // fields removed but weren't migrated by the user
101
+ if (newSchema.version > 1) {
102
+ engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
103
+ for (const name of autoMigratedCollections) {
104
+ await engine.migrate(name, autoMigration(name));
105
+ migratedCollections.push(name);
106
+ }
107
+ const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
108
+ if (unmigrated.length > 0) {
109
+ // TODO: does this deserve a full-on error?
110
+ console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
111
+ }
112
+ }
113
+ },
114
+ removedCollections,
115
+ addedIndexes,
116
+ removedIndexes,
117
+ allCollections: Object.keys(newSchema.collections),
118
+ changedCollections,
119
+ addedCollections,
120
+ oldCollections: Object.keys(oldSchema.collections),
121
+ oldSchema,
122
+ newSchema,
123
+ };
124
+ }
125
+ export function migrationRange(from, to) {
126
+ return [...Array(to - from).keys()].map((i) => 1 + i + from);
127
+ }
128
+ function getIndexes(collection) {
129
+ if (!collection)
130
+ return [];
131
+ return [
132
+ ...Object.keys(collection.indexes || {}).map((key) => ({
133
+ name: key,
134
+ multiEntry: ['array', 'string[]', 'number[]', 'boolean[]'].includes(collection.indexes[key].type),
135
+ synthetic: true,
136
+ compound: false,
137
+ })),
138
+ ...Object.keys(collection.compounds || {}).map((key) => ({
139
+ name: key,
140
+ multiEntry: collection.compounds[key].of.some((fieldName) => (collection.fields[fieldName] || collection.indexes[fieldName])
141
+ .type === 'array'),
142
+ synthetic: false,
143
+ compound: true,
144
+ })),
145
+ ];
146
+ }
147
+ export function createDefaultMigration(schema, newSchema) {
148
+ let oldSchema = newSchema
149
+ ? schema
150
+ : {
151
+ version: 0,
152
+ collections: {},
153
+ };
154
+ return migrate(oldSchema, newSchema || schema, async ({ migrate, info }) => {
155
+ if ((newSchema || schema).version === 1)
156
+ return;
157
+ for (const collection of info.changedCollections) {
158
+ // @ts-ignore indefinite type resolution
159
+ await migrate(collection, (old) => old);
160
+ }
161
+ });
162
+ }
163
+ export function createMigration(maybeOldSchema, maybeNewSchemaOrProcedure, maybeProcedure) {
164
+ const isProcedureSecondArgument = typeof maybeNewSchemaOrProcedure === 'function' ||
165
+ maybeNewSchemaOrProcedure === undefined;
166
+ const oldSchema = isProcedureSecondArgument ? emptySchema : maybeOldSchema;
167
+ const newSchema = isProcedureSecondArgument
168
+ ? maybeOldSchema
169
+ : maybeNewSchemaOrProcedure;
170
+ const procedure = isProcedureSecondArgument
171
+ ? maybeNewSchemaOrProcedure
172
+ : maybeProcedure;
173
+ assert(oldSchema, 'Invalid arguments to createMigration');
174
+ assert(newSchema, 'Invalid arguments to createMigration');
175
+ const { changedCollections, addedCollections, removedCollections, addedIndexes, removedIndexes, autoMigratedCollections, autoMigration, } = getMigrationInfo(oldSchema, newSchema);
176
+ return {
177
+ version: newSchema.version,
178
+ migrate: async (engine) => {
179
+ const migratedCollections = [];
180
+ const migrate = async (collection, strategy) => {
181
+ const auto = autoMigration(collection);
182
+ const wrapped = async (val) => {
183
+ const baseValue = await strategy(val);
184
+ // assign OID from original value in case user's strategy
185
+ // involves cloning
186
+ assignOid(baseValue, getOid(val));
187
+ const result = auto(baseValue);
188
+ return result;
189
+ };
190
+ // @ts-ignore
191
+ await engine.migrate(collection, wrapped);
192
+ migratedCollections.push(collection);
193
+ // since the user migrated this one and we wrap their
194
+ // strategy with auto-migration, we can remove it from
195
+ // the auto-migration list
196
+ autoMigratedCollections.delete(collection);
197
+ };
198
+ await (procedure === null || procedure === void 0 ? void 0 : procedure({
199
+ migrate,
200
+ info: {
201
+ changedCollections,
202
+ addedCollections,
203
+ removedCollections,
204
+ },
205
+ queries: engine.queries,
206
+ mutations: engine.mutations,
207
+ }));
208
+ // mandatory migration of fields which had defaults added or
209
+ // fields removed but weren't migrated by the user
210
+ if (newSchema.version > 1) {
211
+ engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
212
+ for (const name of autoMigratedCollections) {
213
+ await engine.migrate(name, autoMigration(name));
214
+ migratedCollections.push(name);
215
+ }
216
+ const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
217
+ if (unmigrated.length > 0) {
218
+ // TODO: does this deserve a full-on error?
219
+ console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
220
+ }
221
+ }
222
+ },
223
+ removedCollections,
224
+ addedIndexes,
225
+ removedIndexes,
226
+ allCollections: Object.keys(newSchema.collections),
227
+ changedCollections,
228
+ addedCollections,
229
+ oldCollections: Object.keys(oldSchema.collections),
230
+ oldSchema,
231
+ newSchema,
232
+ };
233
+ }
234
+ // common tools
235
+ function getMigrationInfo(oldSchema, newSchema) {
236
+ const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
237
+ stableStringify(oldSchema.collections[key]) !==
238
+ stableStringify(newSchema.collections[key]));
239
+ const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
240
+ const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
241
+ // collections which added one or more field defaults
242
+ const autoMigratedCollections = new Set();
243
+ for (const collection of changedCollections) {
244
+ const oldFields = oldSchema.collections[collection].fields;
245
+ const newFields = newSchema.collections[collection].fields;
246
+ // a new default was added - we can auto-migrate it
247
+ if (Object.keys(newFields).some((key) => !hasDefault(oldFields[key]) && hasDefault(newFields[key]))) {
248
+ autoMigratedCollections.add(collection);
249
+ }
250
+ // a field was removed - we can auto-migrate it
251
+ if (Object.keys(oldFields).some((key) => !newFields[key])) {
252
+ autoMigratedCollections.add(collection);
253
+ }
254
+ }
255
+ const addedIndexes = {};
256
+ const removedIndexes = {};
257
+ for (const changed of [...changedCollections, ...addedCollections]) {
258
+ const oldIndexes = getIndexes(oldSchema.collections[changed]);
259
+ const newIndexes = getIndexes(newSchema.collections[changed]);
260
+ const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
261
+ const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
262
+ if (added.length > 0) {
263
+ addedIndexes[changed] = added;
264
+ // FIXME: don't o(n^2) this
265
+ if (changedCollections.includes(changed)) {
266
+ autoMigratedCollections.add(changed);
267
+ }
268
+ }
269
+ if (removed.length > 0) {
270
+ removedIndexes[changed] = removed;
271
+ // FIXME: don't o(n^2) this
272
+ if (changedCollections.includes(changed)) {
273
+ autoMigratedCollections.add(changed);
274
+ }
275
+ }
276
+ }
277
+ const withDefaults = (collectionName, val) => {
278
+ return addFieldDefaults(newSchema.collections[collectionName], val);
279
+ };
280
+ const autoMigration = (collectionName) => (val) => {
281
+ const collection = newSchema.collections[collectionName];
282
+ return addFieldDefaults(collection, removeExtraProperties(collection, val));
283
+ };
284
+ return {
285
+ changedCollections,
286
+ addedCollections,
287
+ removedCollections,
288
+ addedIndexes,
289
+ removedIndexes,
290
+ autoMigratedCollections,
291
+ withDefaults,
292
+ autoMigration,
293
+ };
294
+ }
295
295
  //# sourceMappingURL=migration.js.map