@tldraw/store 5.2.0-next.ee0fa4d6244f → 5.2.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.
- package/DOCS.md +790 -0
- package/README.md +9 -1
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/ImmutableMap.js +0 -13
- package/dist-cjs/lib/ImmutableMap.js.map +2 -2
- package/dist-cjs/lib/RecordType.js +1 -1
- package/dist-cjs/lib/RecordType.js.map +2 -2
- package/dist-cjs/lib/RecordsDiff.js +26 -14
- package/dist-cjs/lib/RecordsDiff.js.map +2 -2
- package/dist-cjs/lib/Store.js +6 -5
- package/dist-cjs/lib/Store.js.map +2 -2
- package/dist-cjs/lib/StoreSchema.js +1 -1
- package/dist-cjs/lib/StoreSchema.js.map +2 -2
- package/dist-cjs/lib/executeQuery.js +1 -1
- package/dist-cjs/lib/executeQuery.js.map +2 -2
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/ImmutableMap.mjs +0 -13
- package/dist-esm/lib/ImmutableMap.mjs.map +2 -2
- package/dist-esm/lib/RecordType.mjs +1 -1
- package/dist-esm/lib/RecordType.mjs.map +2 -2
- package/dist-esm/lib/RecordsDiff.mjs +26 -14
- package/dist-esm/lib/RecordsDiff.mjs.map +2 -2
- package/dist-esm/lib/Store.mjs +7 -6
- package/dist-esm/lib/Store.mjs.map +2 -2
- package/dist-esm/lib/StoreSchema.mjs +1 -1
- package/dist-esm/lib/StoreSchema.mjs.map +2 -2
- package/dist-esm/lib/executeQuery.mjs +1 -1
- package/dist-esm/lib/executeQuery.mjs.map +2 -2
- package/package.json +9 -5
- package/src/lib/{test/AtomMap.test.ts → AtomMap.test.ts} +77 -111
- package/src/lib/AtomSet.test.ts +116 -0
- package/src/lib/BaseRecord.test.ts +10 -22
- package/src/lib/ImmutableMap.test.ts +114 -71
- package/src/lib/ImmutableMap.ts +1 -0
- package/src/lib/IncrementalSetConstructor.test.ts +76 -81
- package/src/lib/RecordType.test.ts +216 -0
- package/src/lib/RecordType.ts +1 -1
- package/src/lib/RecordsDiff.test.ts +112 -106
- package/src/lib/RecordsDiff.ts +43 -18
- package/src/lib/Store.test.ts +570 -630
- package/src/lib/Store.ts +9 -10
- package/src/lib/StoreListeners.test.ts +462 -0
- package/src/lib/StoreQueries.test.ts +586 -434
- package/src/lib/StoreSchema.test.ts +1012 -174
- package/src/lib/StoreSchema.ts +1 -1
- package/src/lib/StoreSideEffects.test.ts +546 -158
- package/src/lib/devFreeze.test.ts +94 -124
- package/src/lib/executeQuery.test.ts +77 -31
- package/src/lib/executeQuery.ts +3 -1
- package/src/lib/migrate.test.ts +273 -296
- package/src/lib/setUtils.test.ts +38 -79
- package/src/lib/test/createMigrations.test.ts +0 -75
- package/src/lib/test/dependsOn.test.ts +0 -166
- package/src/lib/test/getMigrationsSince.test.ts +0 -121
- package/src/lib/test/migrate.test.ts +0 -118
- package/src/lib/test/migratePersistedRecord.test.ts +0 -265
- package/src/lib/test/migrationCaching.test.ts +0 -209
- package/src/lib/test/recordStore.test.ts +0 -1567
- package/src/lib/test/recordStoreQueries.test.ts +0 -814
- package/src/lib/test/recordType.test.ts +0 -19
- package/src/lib/test/sortMigrations.test.ts +0 -83
- package/src/lib/test/upgradeSchema.test.ts +0 -80
- package/src/lib/test/validate.test.ts +0 -178
- package/src/lib/test/validateMigrations.test.ts +0 -165
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import assert from 'assert'
|
|
2
|
-
import { BaseRecord, RecordId } from '../BaseRecord'
|
|
3
|
-
import { MigrationSequence } from '../migrate'
|
|
4
|
-
import { createRecordType } from '../RecordType'
|
|
5
|
-
import { SerializedSchemaV2, StoreSchema } from '../StoreSchema'
|
|
6
|
-
|
|
7
|
-
const mockSequence = ({
|
|
8
|
-
id,
|
|
9
|
-
retroactive,
|
|
10
|
-
versions,
|
|
11
|
-
filter,
|
|
12
|
-
}: {
|
|
13
|
-
id: string
|
|
14
|
-
retroactive: boolean
|
|
15
|
-
versions: number
|
|
16
|
-
filter?(r: TestRecordType): boolean
|
|
17
|
-
}): MigrationSequence => ({
|
|
18
|
-
sequenceId: id,
|
|
19
|
-
retroactive,
|
|
20
|
-
sequence: new Array(versions).fill(0).map((_, i) => ({
|
|
21
|
-
id: `${id}/${i + 1}`,
|
|
22
|
-
scope: 'record',
|
|
23
|
-
filter: filter as any,
|
|
24
|
-
up(r) {
|
|
25
|
-
const record = r as TestRecordType
|
|
26
|
-
record.versions[id] ??= 0
|
|
27
|
-
record.versions[id]++
|
|
28
|
-
// noop
|
|
29
|
-
},
|
|
30
|
-
down(r) {
|
|
31
|
-
const record = r as TestRecordType
|
|
32
|
-
record.versions[id]--
|
|
33
|
-
},
|
|
34
|
-
})),
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
interface TestRecordType extends BaseRecord<'test', RecordId<TestRecordType>> {
|
|
38
|
-
versions: Record<string, number>
|
|
39
|
-
}
|
|
40
|
-
const TestRecordType = createRecordType<TestRecordType>('test', {
|
|
41
|
-
scope: 'document',
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
const makeSchema = (migrations: MigrationSequence[]) => {
|
|
45
|
-
return StoreSchema.create({ test: TestRecordType }, { migrations })
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const makePersistedSchema = (...args: Array<[migrations: MigrationSequence, version: number]>) => {
|
|
49
|
-
return {
|
|
50
|
-
schemaVersion: 2,
|
|
51
|
-
sequences: Object.fromEntries(args.map(([m, v]) => [m.sequenceId, v])),
|
|
52
|
-
} satisfies SerializedSchemaV2
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const makeTestRecord = (persistedSchema: SerializedSchemaV2) => {
|
|
56
|
-
return TestRecordType.create({
|
|
57
|
-
versions: Object.fromEntries(
|
|
58
|
-
Object.keys(persistedSchema.sequences).map((id) => [id, persistedSchema.sequences[id]])
|
|
59
|
-
),
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
test('going up from 0', () => {
|
|
64
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 2 })
|
|
65
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
66
|
-
const schema = makeSchema([foo, bar])
|
|
67
|
-
const persistedSchema = makePersistedSchema([foo, 0], [bar, 0])
|
|
68
|
-
|
|
69
|
-
const r = makeTestRecord(persistedSchema)
|
|
70
|
-
expect(r.versions).toEqual({ foo: 0, bar: 0 })
|
|
71
|
-
const update = schema.migratePersistedRecord(r, persistedSchema)
|
|
72
|
-
assert(update.type === 'success', 'the update should be successful')
|
|
73
|
-
|
|
74
|
-
// the original record did not change
|
|
75
|
-
expect(r.versions).toEqual({ foo: 0, bar: 0 })
|
|
76
|
-
|
|
77
|
-
// the updated record has the new versions
|
|
78
|
-
expect((update.value as TestRecordType).versions).toEqual({ foo: 2, bar: 3 })
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test('going up with a retroactive: true and a retroactive: false', () => {
|
|
82
|
-
const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
|
|
83
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
84
|
-
const schema = makeSchema([foo, bar])
|
|
85
|
-
const persistedSchema = makePersistedSchema()
|
|
86
|
-
|
|
87
|
-
const r = makeTestRecord(persistedSchema)
|
|
88
|
-
expect(r.versions).toEqual({})
|
|
89
|
-
const update = schema.migratePersistedRecord(r, persistedSchema)
|
|
90
|
-
assert(update.type === 'success', 'the update should be successful')
|
|
91
|
-
|
|
92
|
-
// the original record did not change
|
|
93
|
-
expect(r.versions).toEqual({})
|
|
94
|
-
|
|
95
|
-
// the updated record has the new versions
|
|
96
|
-
expect((update.value as TestRecordType).versions).toEqual({ foo: 2 })
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
test('going down to 0s', () => {
|
|
100
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 2 })
|
|
101
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
102
|
-
const schema = makeSchema([foo, bar])
|
|
103
|
-
const persistedSchema = makePersistedSchema([foo, 0], [bar, 0])
|
|
104
|
-
|
|
105
|
-
const r = makeTestRecord(schema.serialize())
|
|
106
|
-
expect(r.versions).toEqual({ foo: 2, bar: 3 })
|
|
107
|
-
const downgrade = schema.migratePersistedRecord(r, persistedSchema, 'down')
|
|
108
|
-
assert(downgrade.type === 'success', 'the downgrade should be successful')
|
|
109
|
-
|
|
110
|
-
// the original record did not change
|
|
111
|
-
expect(r.versions).toEqual({ foo: 2, bar: 3 })
|
|
112
|
-
|
|
113
|
-
// the downgraded record has the new versions
|
|
114
|
-
expect((downgrade.value as TestRecordType).versions).toEqual({ foo: 0, bar: 0 })
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
test('going down with a retroactive: true and a retroactive: false', () => {
|
|
118
|
-
const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
|
|
119
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
120
|
-
const schema = makeSchema([foo, bar])
|
|
121
|
-
const persistedSchema = makePersistedSchema()
|
|
122
|
-
|
|
123
|
-
const r = makeTestRecord(schema.serialize())
|
|
124
|
-
expect(r.versions).toEqual({ foo: 2, bar: 3 })
|
|
125
|
-
const downgrade = schema.migratePersistedRecord(r, persistedSchema, 'down')
|
|
126
|
-
assert(downgrade.type === 'success', 'the downgrade should be successful')
|
|
127
|
-
|
|
128
|
-
// the original record did not change
|
|
129
|
-
expect(r.versions).toEqual({ foo: 2, bar: 3 })
|
|
130
|
-
|
|
131
|
-
// only the foo migrations were undone
|
|
132
|
-
expect((downgrade.value as TestRecordType).versions).toEqual({ foo: 0, bar: 3 })
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
test('going up with no changes', () => {
|
|
136
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 2 })
|
|
137
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
138
|
-
const schema = makeSchema([foo, bar])
|
|
139
|
-
const persistedSchema = makePersistedSchema([foo, 2], [bar, 3])
|
|
140
|
-
|
|
141
|
-
const r = makeTestRecord(persistedSchema)
|
|
142
|
-
expect(r.versions).toEqual({ foo: 2, bar: 3 })
|
|
143
|
-
const update = schema.migratePersistedRecord(r, persistedSchema)
|
|
144
|
-
assert(update.type === 'success', 'the update should be successful')
|
|
145
|
-
|
|
146
|
-
// the returned record should be the the input record, i.e. it should not have allocated a new record
|
|
147
|
-
expect(r).toBe(update.value)
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
test('going down with no changes', () => {
|
|
151
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 2 })
|
|
152
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
153
|
-
const schema = makeSchema([foo, bar])
|
|
154
|
-
const persistedSchema = makePersistedSchema([foo, 2], [bar, 3])
|
|
155
|
-
|
|
156
|
-
const r = makeTestRecord(persistedSchema)
|
|
157
|
-
expect(r.versions).toEqual({ foo: 2, bar: 3 })
|
|
158
|
-
const update = schema.migratePersistedRecord(r, persistedSchema, 'down')
|
|
159
|
-
assert(update.type === 'success', 'the update should be successful')
|
|
160
|
-
|
|
161
|
-
// the returned record should be the the input record, i.e. it should not have allocated a new record
|
|
162
|
-
expect(r).toBe(update.value)
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
test('respects filters', () => {
|
|
166
|
-
const foo = mockSequence({
|
|
167
|
-
id: 'foo',
|
|
168
|
-
retroactive: false,
|
|
169
|
-
versions: 2,
|
|
170
|
-
filter: (r) => (r as any).foo === true,
|
|
171
|
-
})
|
|
172
|
-
const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
|
|
173
|
-
const schema = makeSchema([foo, bar])
|
|
174
|
-
const persistedSchema = makePersistedSchema([foo, 0], [bar, 0])
|
|
175
|
-
|
|
176
|
-
const r = makeTestRecord(persistedSchema)
|
|
177
|
-
const update = schema.migratePersistedRecord(r, persistedSchema, 'up')
|
|
178
|
-
assert(update.type === 'success', 'the update should be successful')
|
|
179
|
-
|
|
180
|
-
// foo migrations shouldn't have been applied
|
|
181
|
-
expect((update.value as TestRecordType).versions).toEqual({ foo: 0, bar: 3 })
|
|
182
|
-
|
|
183
|
-
const r2 = { ...r, foo: true }
|
|
184
|
-
const update2 = schema.migratePersistedRecord(r2, persistedSchema, 'up')
|
|
185
|
-
assert(update2.type === 'success', 'the update should be successful')
|
|
186
|
-
|
|
187
|
-
// foo migrations should have been applied
|
|
188
|
-
expect((update2.value as TestRecordType).versions).toEqual({ foo: 2, bar: 3 })
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
test('does not go up or down if theres a store migration in the path', () => {
|
|
192
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 3 })
|
|
193
|
-
foo.sequence[1] = {
|
|
194
|
-
id: 'foo/2',
|
|
195
|
-
scope: 'store',
|
|
196
|
-
up() {
|
|
197
|
-
// noop
|
|
198
|
-
},
|
|
199
|
-
down() {
|
|
200
|
-
// noop
|
|
201
|
-
},
|
|
202
|
-
}
|
|
203
|
-
const schema = makeSchema([foo])
|
|
204
|
-
const v0Schema = makePersistedSchema([foo, 0])
|
|
205
|
-
|
|
206
|
-
const r0 = makeTestRecord(v0Schema)
|
|
207
|
-
const r3 = makeTestRecord(schema.serialize())
|
|
208
|
-
const update = schema.migratePersistedRecord(r0, v0Schema, 'up')
|
|
209
|
-
expect(update.type).toBe('error')
|
|
210
|
-
const update2 = schema.migratePersistedRecord(r3, v0Schema, 'down')
|
|
211
|
-
expect(update2.type).toBe('error')
|
|
212
|
-
|
|
213
|
-
// snapshot migration up should still work
|
|
214
|
-
const update3 = schema.migrateStoreSnapshot({
|
|
215
|
-
schema: v0Schema,
|
|
216
|
-
store: { [r0.id]: r0 },
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
assert(update3.type === 'success', 'the update should be successful')
|
|
220
|
-
expect((update3.value[r0.id] as TestRecordType).versions).toEqual({ foo: 2 })
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
test('does not go down if theres a migrations without the down migrator in the path', () => {
|
|
224
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 3 })
|
|
225
|
-
delete (foo.sequence[1] as any).down
|
|
226
|
-
const schema = makeSchema([foo])
|
|
227
|
-
const v0Schema = makePersistedSchema([foo, 0])
|
|
228
|
-
|
|
229
|
-
// going up still works
|
|
230
|
-
const r0 = makeTestRecord(v0Schema)
|
|
231
|
-
const update = schema.migratePersistedRecord(r0, v0Schema, 'up')
|
|
232
|
-
expect(update.type).toBe('success')
|
|
233
|
-
|
|
234
|
-
// going down does not
|
|
235
|
-
const r3 = makeTestRecord(schema.serialize())
|
|
236
|
-
const update2 = schema.migratePersistedRecord(r3, v0Schema, 'down')
|
|
237
|
-
expect(update2.type).toBe('error')
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
test('allows returning a new record from the migrator fn', () => {
|
|
241
|
-
const foo = mockSequence({ id: 'foo', retroactive: false, versions: 3 })
|
|
242
|
-
foo.sequence[1] = {
|
|
243
|
-
id: 'foo/2',
|
|
244
|
-
scope: 'record',
|
|
245
|
-
up(r) {
|
|
246
|
-
const record = r as TestRecordType
|
|
247
|
-
return { ...record, versions: { ...record.versions, foo: 2 } }
|
|
248
|
-
},
|
|
249
|
-
down(r) {
|
|
250
|
-
const record = r as TestRecordType
|
|
251
|
-
return { ...record, versions: { ...record.versions, foo: 1 } }
|
|
252
|
-
},
|
|
253
|
-
}
|
|
254
|
-
const schema = makeSchema([foo])
|
|
255
|
-
const v0Schema = makePersistedSchema([foo, 0])
|
|
256
|
-
|
|
257
|
-
const r0 = makeTestRecord(v0Schema)
|
|
258
|
-
const r3 = makeTestRecord(schema.serialize())
|
|
259
|
-
const update = schema.migratePersistedRecord(r0, v0Schema, 'up')
|
|
260
|
-
assert(update.type === 'success', 'the update should be successful')
|
|
261
|
-
expect((update.value as TestRecordType).versions).toEqual({ foo: 3 })
|
|
262
|
-
const update2 = schema.migratePersistedRecord(r3, v0Schema, 'down')
|
|
263
|
-
assert(update2.type === 'success', 'the update should be successful')
|
|
264
|
-
expect((update2.value as TestRecordType).versions).toEqual({ foo: 0 })
|
|
265
|
-
})
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-deprecated */
|
|
2
|
-
import { assert } from '@tldraw/utils'
|
|
3
|
-
import {
|
|
4
|
-
BaseRecord,
|
|
5
|
-
Migration,
|
|
6
|
-
RecordId,
|
|
7
|
-
createMigrationIds,
|
|
8
|
-
createMigrationSequence,
|
|
9
|
-
createRecordType,
|
|
10
|
-
} from '../../'
|
|
11
|
-
import { StoreSchema } from '../StoreSchema'
|
|
12
|
-
|
|
13
|
-
interface TestRecord extends BaseRecord<'test', RecordId<TestRecord>> {
|
|
14
|
-
name: string
|
|
15
|
-
version: number
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
describe('StoreSchema migration caching', () => {
|
|
19
|
-
// Create migration IDs
|
|
20
|
-
const TestVersions = createMigrationIds('com.tldraw.test', {
|
|
21
|
-
AddVersion: 1,
|
|
22
|
-
UpdateVersion: 2,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
// Create a simple schema with migrations
|
|
26
|
-
const createTestSchema = (version: number) => {
|
|
27
|
-
const TestRecordType = createRecordType<TestRecord>('test', {
|
|
28
|
-
scope: 'document',
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const sequence: Migration[] = []
|
|
32
|
-
|
|
33
|
-
if (version > 1) {
|
|
34
|
-
sequence.push({
|
|
35
|
-
id: TestVersions.AddVersion,
|
|
36
|
-
scope: 'record',
|
|
37
|
-
up: (record: any) => {
|
|
38
|
-
// Mutate the record in place
|
|
39
|
-
record.version = 2
|
|
40
|
-
// Don't return anything
|
|
41
|
-
},
|
|
42
|
-
down: (record: any) => {
|
|
43
|
-
record.version = 1
|
|
44
|
-
// Don't return anything
|
|
45
|
-
},
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (version > 2) {
|
|
50
|
-
sequence.push({
|
|
51
|
-
id: TestVersions.UpdateVersion,
|
|
52
|
-
scope: 'record',
|
|
53
|
-
up: (record: any) => {
|
|
54
|
-
record.version = 3
|
|
55
|
-
// Don't return anything
|
|
56
|
-
},
|
|
57
|
-
down: (record: any) => {
|
|
58
|
-
record.version = 2
|
|
59
|
-
// Don't return anything
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const schema = StoreSchema.create(
|
|
65
|
-
{
|
|
66
|
-
test: TestRecordType,
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
migrations: [createMigrationSequence({ sequenceId: 'com.tldraw.test', sequence })],
|
|
70
|
-
}
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
return schema
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
it('should cache migration results and return same array reference', () => {
|
|
77
|
-
const schema = createTestSchema(3)
|
|
78
|
-
const oldSchema = schema.serializeEarliestVersion()
|
|
79
|
-
|
|
80
|
-
// First call should create the migrations array
|
|
81
|
-
const migrations1 = schema.getMigrationsSince(oldSchema)
|
|
82
|
-
assert(migrations1.ok)
|
|
83
|
-
expect(migrations1.value).toHaveLength(2)
|
|
84
|
-
|
|
85
|
-
// Second call should return the same array reference (cached)
|
|
86
|
-
const migrations2 = schema.getMigrationsSince(oldSchema)
|
|
87
|
-
assert(migrations2.ok)
|
|
88
|
-
expect(migrations2.value).toBe(migrations1.value) // Same array reference
|
|
89
|
-
|
|
90
|
-
// Third call should also return the same array reference
|
|
91
|
-
const migrations3 = schema.getMigrationsSince(oldSchema)
|
|
92
|
-
assert(migrations3.ok)
|
|
93
|
-
expect(migrations3.value).toBe(migrations1.value)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('should not cache when schema versions are different', () => {
|
|
97
|
-
const schema = createTestSchema(3)
|
|
98
|
-
const oldSchema = schema.serializeEarliestVersion()
|
|
99
|
-
|
|
100
|
-
// Call with original schema
|
|
101
|
-
const migrations1 = schema.getMigrationsSince(oldSchema)
|
|
102
|
-
expect(migrations1.ok).toBe(true)
|
|
103
|
-
if (!migrations1.ok) throw new Error('Expected migrations1 to be ok')
|
|
104
|
-
|
|
105
|
-
// Create a different schema version by using a schema with version 2
|
|
106
|
-
const schemaV2 = createTestSchema(2)
|
|
107
|
-
const schemaV2Serialized = schemaV2.serializeEarliestVersion()
|
|
108
|
-
const migrations2 = schema.getMigrationsSince(schemaV2Serialized)
|
|
109
|
-
expect(migrations2.ok).toBe(true)
|
|
110
|
-
if (!migrations2.ok) throw new Error('Expected migrations2 to be ok')
|
|
111
|
-
|
|
112
|
-
// Should be different arrays (no cache hit)
|
|
113
|
-
expect(migrations2.value).not.toBe(migrations1.value)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('should handle mutateInputStore: true with migrators that return void', () => {
|
|
117
|
-
const schema = createTestSchema(3)
|
|
118
|
-
const oldSchema = schema.serializeEarliestVersion()
|
|
119
|
-
|
|
120
|
-
const store = {
|
|
121
|
-
test1: {
|
|
122
|
-
id: 'test1',
|
|
123
|
-
name: 'Test 1',
|
|
124
|
-
version: 1,
|
|
125
|
-
typeName: 'test',
|
|
126
|
-
},
|
|
127
|
-
test2: {
|
|
128
|
-
id: 'test2',
|
|
129
|
-
name: 'Test 2',
|
|
130
|
-
version: 1,
|
|
131
|
-
typeName: 'test',
|
|
132
|
-
},
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Test with mutateInputStore: true
|
|
136
|
-
const result1 = schema.migrateStoreSnapshot(
|
|
137
|
-
{ store, schema: oldSchema },
|
|
138
|
-
{ mutateInputStore: true }
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
assert(result1.type === 'success')
|
|
142
|
-
expect((result1.value as any).test1.version).toBe(3)
|
|
143
|
-
expect((result1.value as any).test2.version).toBe(3)
|
|
144
|
-
|
|
145
|
-
// The input store should be mutated in place
|
|
146
|
-
expect(result1.value).toBe(store)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('should handle mutateInputStore: false with migrators that return void', () => {
|
|
150
|
-
const schema = createTestSchema(3)
|
|
151
|
-
const oldSchema = schema.serializeEarliestVersion()
|
|
152
|
-
|
|
153
|
-
const store = {
|
|
154
|
-
test1: {
|
|
155
|
-
id: 'test1',
|
|
156
|
-
name: 'Test 1',
|
|
157
|
-
version: 1,
|
|
158
|
-
typeName: 'test',
|
|
159
|
-
},
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Test with mutateInputStore: false (default)
|
|
163
|
-
const result = schema.migrateStoreSnapshot({ store, schema: oldSchema })
|
|
164
|
-
|
|
165
|
-
assert(result.type === 'success')
|
|
166
|
-
expect((result.value as any).test1.version).toBe(3)
|
|
167
|
-
|
|
168
|
-
// The input store should NOT be mutated
|
|
169
|
-
expect(store.test1.version).toBe(1)
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
it('should handle empty migration list caching', () => {
|
|
173
|
-
const schema = createTestSchema(1) // No migrations
|
|
174
|
-
const oldSchema = schema.serializeEarliestVersion()
|
|
175
|
-
|
|
176
|
-
// First call
|
|
177
|
-
const migrations1 = schema.getMigrationsSince(oldSchema)
|
|
178
|
-
assert(migrations1.ok)
|
|
179
|
-
|
|
180
|
-
expect(migrations1.value).toHaveLength(0)
|
|
181
|
-
|
|
182
|
-
// Second call should return same array reference
|
|
183
|
-
const migrations2 = schema.getMigrationsSince(oldSchema)
|
|
184
|
-
assert(migrations2.ok)
|
|
185
|
-
expect(migrations2.value).toBe(migrations1.value)
|
|
186
|
-
expect(migrations2.value).toHaveLength(0)
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
it('should handle incompatible schema caching', () => {
|
|
190
|
-
const schema = createTestSchema(3)
|
|
191
|
-
const incompatibleSchema = {
|
|
192
|
-
schemaVersion: 1 as const,
|
|
193
|
-
storeVersion: 1,
|
|
194
|
-
recordVersions: {
|
|
195
|
-
test: {
|
|
196
|
-
version: 999, // Much higher version than what we support
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// First call should fail
|
|
202
|
-
const migrations1 = schema.getMigrationsSince(incompatibleSchema)
|
|
203
|
-
expect(migrations1.ok).toBe(false)
|
|
204
|
-
|
|
205
|
-
// Second call should also fail (but might be cached)
|
|
206
|
-
const migrations2 = schema.getMigrationsSince(incompatibleSchema)
|
|
207
|
-
expect(migrations2.ok).toBe(false)
|
|
208
|
-
})
|
|
209
|
-
})
|