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

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 (151) 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 +457 -457
  19. package/dist/cjs/oids.test.d.ts +1 -1
  20. package/dist/cjs/oids.test.js +348 -348
  21. package/dist/cjs/operation.d.ts +139 -139
  22. package/dist/cjs/operation.js +545 -545
  23. package/dist/cjs/operation.test.d.ts +1 -1
  24. package/dist/cjs/operation.test.js +529 -529
  25. package/dist/cjs/patch.d.ts +26 -26
  26. package/dist/cjs/patch.js +226 -226
  27. package/dist/cjs/presence.d.ts +27 -27
  28. package/dist/cjs/presence.js +2 -2
  29. package/dist/cjs/protocol.d.ts +145 -145
  30. package/dist/cjs/protocol.js +3 -3
  31. package/dist/cjs/refs.d.ts +7 -7
  32. package/dist/cjs/refs.js +29 -29
  33. package/dist/cjs/replica.d.ts +28 -28
  34. package/dist/cjs/replica.js +28 -28
  35. package/dist/cjs/schema/defaults.test.d.ts +1 -1
  36. package/dist/cjs/schema/defaults.test.js +20 -20
  37. package/dist/cjs/schema/fields.d.ts +9 -9
  38. package/dist/cjs/schema/fields.js +144 -144
  39. package/dist/cjs/schema/index.d.ts +8 -8
  40. package/dist/cjs/schema/index.js +51 -51
  41. package/dist/cjs/schema/indexFilters.d.ts +6 -6
  42. package/dist/cjs/schema/indexFilters.js +30 -30
  43. package/dist/cjs/schema/types/collection.d.ts +23 -23
  44. package/dist/cjs/schema/types/collection.js +2 -2
  45. package/dist/cjs/schema/types/compounds.d.ts +11 -11
  46. package/dist/cjs/schema/types/compounds.js +2 -2
  47. package/dist/cjs/schema/types/fields.d.ts +75 -75
  48. package/dist/cjs/schema/types/fields.js +2 -2
  49. package/dist/cjs/schema/types/filters.d.ts +29 -29
  50. package/dist/cjs/schema/types/filters.js +2 -2
  51. package/dist/cjs/schema/types/shapes.d.ts +21 -21
  52. package/dist/cjs/schema/types/shapes.js +2 -2
  53. package/dist/cjs/schema/types/synthetics.d.ts +37 -37
  54. package/dist/cjs/schema/types/synthetics.js +2 -2
  55. package/dist/cjs/schema/types.d.ts +18 -18
  56. package/dist/cjs/schema/types.js +22 -22
  57. package/dist/cjs/schema/validation.d.ts +3 -3
  58. package/dist/cjs/schema/validation.js +86 -86
  59. package/dist/cjs/timestamp.d.ts +50 -50
  60. package/dist/cjs/timestamp.js +251 -251
  61. package/dist/cjs/timestamp.test.d.ts +1 -1
  62. package/dist/cjs/timestamp.test.js +104 -104
  63. package/dist/cjs/undo.d.ts +3 -3
  64. package/dist/cjs/undo.js +198 -198
  65. package/dist/cjs/utils.d.ts +20 -20
  66. package/dist/cjs/utils.js +145 -145
  67. package/dist/cjs/utils.test.d.ts +1 -1
  68. package/dist/cjs/utils.test.js +36 -36
  69. package/dist/esm/EventSubscriber.d.ts +17 -17
  70. package/dist/esm/EventSubscriber.js +62 -62
  71. package/dist/esm/baseline.d.ts +5 -5
  72. package/dist/esm/baseline.js +1 -1
  73. package/dist/esm/batching.d.ts +42 -42
  74. package/dist/esm/batching.js +86 -86
  75. package/dist/esm/files.d.ts +19 -19
  76. package/dist/esm/files.js +12 -12
  77. package/dist/esm/index.d.ts +19 -19
  78. package/dist/esm/index.js +16 -16
  79. package/dist/esm/indexes.d.ts +17 -17
  80. package/dist/esm/indexes.js +130 -130
  81. package/dist/esm/indexes.test.d.ts +1 -1
  82. package/dist/esm/indexes.test.js +125 -125
  83. package/dist/esm/migration.d.ts +172 -172
  84. package/dist/esm/migration.js +294 -294
  85. package/dist/esm/oids.d.ts +100 -100
  86. package/dist/esm/oids.js +422 -422
  87. package/dist/esm/oids.test.d.ts +1 -1
  88. package/dist/esm/oids.test.js +346 -346
  89. package/dist/esm/operation.d.ts +139 -139
  90. package/dist/esm/operation.js +530 -530
  91. package/dist/esm/operation.test.d.ts +1 -1
  92. package/dist/esm/operation.test.js +527 -527
  93. package/dist/esm/patch.d.ts +26 -26
  94. package/dist/esm/patch.js +222 -222
  95. package/dist/esm/presence.d.ts +27 -27
  96. package/dist/esm/presence.js +1 -1
  97. package/dist/esm/protocol.d.ts +145 -145
  98. package/dist/esm/protocol.js +2 -2
  99. package/dist/esm/refs.d.ts +7 -7
  100. package/dist/esm/refs.js +22 -22
  101. package/dist/esm/replica.d.ts +28 -28
  102. package/dist/esm/replica.js +25 -25
  103. package/dist/esm/schema/defaults.test.d.ts +1 -1
  104. package/dist/esm/schema/defaults.test.js +18 -18
  105. package/dist/esm/schema/fields.d.ts +9 -9
  106. package/dist/esm/schema/fields.js +133 -133
  107. package/dist/esm/schema/index.d.ts +8 -8
  108. package/dist/esm/schema/index.js +32 -32
  109. package/dist/esm/schema/indexFilters.d.ts +6 -6
  110. package/dist/esm/schema/indexFilters.js +22 -22
  111. package/dist/esm/schema/types/collection.d.ts +23 -23
  112. package/dist/esm/schema/types/collection.js +1 -1
  113. package/dist/esm/schema/types/compounds.d.ts +11 -11
  114. package/dist/esm/schema/types/compounds.js +1 -1
  115. package/dist/esm/schema/types/fields.d.ts +75 -75
  116. package/dist/esm/schema/types/fields.js +1 -1
  117. package/dist/esm/schema/types/filters.d.ts +29 -29
  118. package/dist/esm/schema/types/filters.js +1 -1
  119. package/dist/esm/schema/types/shapes.d.ts +21 -21
  120. package/dist/esm/schema/types/shapes.js +1 -1
  121. package/dist/esm/schema/types/synthetics.d.ts +37 -37
  122. package/dist/esm/schema/types/synthetics.js +1 -1
  123. package/dist/esm/schema/types.d.ts +18 -18
  124. package/dist/esm/schema/types.js +6 -6
  125. package/dist/esm/schema/validation.d.ts +3 -3
  126. package/dist/esm/schema/validation.js +81 -81
  127. package/dist/esm/timestamp.d.ts +50 -50
  128. package/dist/esm/timestamp.js +234 -234
  129. package/dist/esm/timestamp.test.d.ts +1 -1
  130. package/dist/esm/timestamp.test.js +102 -102
  131. package/dist/esm/undo.d.ts +3 -3
  132. package/dist/esm/undo.js +194 -194
  133. package/dist/esm/utils.d.ts +20 -20
  134. package/dist/esm/utils.js +127 -127
  135. package/dist/esm/utils.test.d.ts +1 -1
  136. package/dist/esm/utils.test.js +34 -34
  137. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  138. package/dist/tsconfig.tsbuildinfo +1 -1
  139. package/package.json +1 -1
  140. package/dist/cjs/files.test.d.ts +0 -1
  141. package/dist/cjs/files.test.js +0 -81
  142. package/dist/cjs/files.test.js.map +0 -1
  143. package/dist/cjs/schema/defaults.d.ts +0 -4
  144. package/dist/cjs/schema/defaults.js +0 -72
  145. package/dist/cjs/schema/defaults.js.map +0 -1
  146. package/dist/esm/files.test.d.ts +0 -1
  147. package/dist/esm/files.test.js +0 -79
  148. package/dist/esm/files.test.js.map +0 -1
  149. package/dist/esm/schema/defaults.d.ts +0 -4
  150. package/dist/esm/schema/defaults.js +0 -66
  151. 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