@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.
Files changed (64) hide show
  1. package/DOCS.md +790 -0
  2. package/README.md +9 -1
  3. package/dist-cjs/index.js +1 -1
  4. package/dist-cjs/lib/ImmutableMap.js +0 -13
  5. package/dist-cjs/lib/ImmutableMap.js.map +2 -2
  6. package/dist-cjs/lib/RecordType.js +1 -1
  7. package/dist-cjs/lib/RecordType.js.map +2 -2
  8. package/dist-cjs/lib/RecordsDiff.js +26 -14
  9. package/dist-cjs/lib/RecordsDiff.js.map +2 -2
  10. package/dist-cjs/lib/Store.js +6 -5
  11. package/dist-cjs/lib/Store.js.map +2 -2
  12. package/dist-cjs/lib/StoreSchema.js +1 -1
  13. package/dist-cjs/lib/StoreSchema.js.map +2 -2
  14. package/dist-cjs/lib/executeQuery.js +1 -1
  15. package/dist-cjs/lib/executeQuery.js.map +2 -2
  16. package/dist-esm/index.mjs +1 -1
  17. package/dist-esm/lib/ImmutableMap.mjs +0 -13
  18. package/dist-esm/lib/ImmutableMap.mjs.map +2 -2
  19. package/dist-esm/lib/RecordType.mjs +1 -1
  20. package/dist-esm/lib/RecordType.mjs.map +2 -2
  21. package/dist-esm/lib/RecordsDiff.mjs +26 -14
  22. package/dist-esm/lib/RecordsDiff.mjs.map +2 -2
  23. package/dist-esm/lib/Store.mjs +7 -6
  24. package/dist-esm/lib/Store.mjs.map +2 -2
  25. package/dist-esm/lib/StoreSchema.mjs +1 -1
  26. package/dist-esm/lib/StoreSchema.mjs.map +2 -2
  27. package/dist-esm/lib/executeQuery.mjs +1 -1
  28. package/dist-esm/lib/executeQuery.mjs.map +2 -2
  29. package/package.json +9 -5
  30. package/src/lib/{test/AtomMap.test.ts → AtomMap.test.ts} +77 -111
  31. package/src/lib/AtomSet.test.ts +116 -0
  32. package/src/lib/BaseRecord.test.ts +10 -22
  33. package/src/lib/ImmutableMap.test.ts +114 -71
  34. package/src/lib/ImmutableMap.ts +1 -0
  35. package/src/lib/IncrementalSetConstructor.test.ts +76 -81
  36. package/src/lib/RecordType.test.ts +216 -0
  37. package/src/lib/RecordType.ts +1 -1
  38. package/src/lib/RecordsDiff.test.ts +112 -106
  39. package/src/lib/RecordsDiff.ts +43 -18
  40. package/src/lib/Store.test.ts +570 -630
  41. package/src/lib/Store.ts +9 -10
  42. package/src/lib/StoreListeners.test.ts +462 -0
  43. package/src/lib/StoreQueries.test.ts +586 -434
  44. package/src/lib/StoreSchema.test.ts +1012 -174
  45. package/src/lib/StoreSchema.ts +1 -1
  46. package/src/lib/StoreSideEffects.test.ts +546 -158
  47. package/src/lib/devFreeze.test.ts +94 -124
  48. package/src/lib/executeQuery.test.ts +77 -31
  49. package/src/lib/executeQuery.ts +3 -1
  50. package/src/lib/migrate.test.ts +273 -296
  51. package/src/lib/setUtils.test.ts +38 -79
  52. package/src/lib/test/createMigrations.test.ts +0 -75
  53. package/src/lib/test/dependsOn.test.ts +0 -166
  54. package/src/lib/test/getMigrationsSince.test.ts +0 -121
  55. package/src/lib/test/migrate.test.ts +0 -118
  56. package/src/lib/test/migratePersistedRecord.test.ts +0 -265
  57. package/src/lib/test/migrationCaching.test.ts +0 -209
  58. package/src/lib/test/recordStore.test.ts +0 -1567
  59. package/src/lib/test/recordStoreQueries.test.ts +0 -814
  60. package/src/lib/test/recordType.test.ts +0 -19
  61. package/src/lib/test/sortMigrations.test.ts +0 -83
  62. package/src/lib/test/upgradeSchema.test.ts +0 -80
  63. package/src/lib/test/validate.test.ts +0 -178
  64. package/src/lib/test/validateMigrations.test.ts +0 -165
@@ -1,105 +1,64 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
  import { diffSets, intersectSets } from './setUtils'
3
3
 
4
- describe('intersectSets', () => {
5
- it('should return intersection of multiple sets', () => {
6
- const set1 = new Set([1, 2, 3, 4])
7
- const set2 = new Set([2, 3, 4, 5])
8
- const set3 = new Set([3, 4, 5, 6])
4
+ // Tests for SPEC.md §25 (set utilities).
5
+ // Rule IDs like [SU1] in test names refer to that document.
9
6
 
10
- const result = intersectSets([set1, set2, set3])
7
+ describe('intersectSets (SU)', () => {
8
+ it('[SU1] returns the elements present in every set', () => {
9
+ expect(
10
+ intersectSets([new Set([1, 2, 3, 4]), new Set([2, 3, 4, 5]), new Set([3, 4, 5, 6])])
11
+ ).toEqual(new Set([3, 4]))
11
12
 
12
- expect(Array.from(result).sort()).toEqual([3, 4])
13
+ expect(intersectSets([new Set([1, 2, 3]), new Set([4, 5, 6])])).toEqual(new Set())
14
+ expect(intersectSets([new Set([1, 2, 3]), new Set(), new Set([2, 3, 4])])).toEqual(new Set())
13
15
  })
14
16
 
15
- it('should return empty set when no sets provided', () => {
16
- const result = intersectSets([])
17
- expect(result.size).toBe(0)
17
+ it('[SU1] no sets yields an empty set', () => {
18
+ expect(intersectSets([])).toEqual(new Set())
18
19
  })
19
20
 
20
- it('should return empty set when no common elements exist', () => {
21
- const set1 = new Set([1, 2, 3])
22
- const set2 = new Set([4, 5, 6])
21
+ it('[SU1] a single set yields a copy', () => {
22
+ const set = new Set([1, 2, 3])
23
+ const result = intersectSets([set])
23
24
 
24
- const result = intersectSets([set1, set2])
25
-
26
- expect(result.size).toBe(0)
27
- })
28
-
29
- it('should return empty set when any set is empty', () => {
30
- const set1 = new Set([1, 2, 3])
31
- const set2 = new Set<number>()
32
- const set3 = new Set([2, 3, 4])
33
-
34
- const result = intersectSets([set1, set2, set3])
35
-
36
- expect(result.size).toBe(0)
37
- })
38
-
39
- it('should return copy of single set', () => {
40
- const set1 = new Set([1, 2, 3])
41
- const result = intersectSets([set1])
42
-
43
- expect(result).not.toBe(set1)
44
- expect(Array.from(result).sort()).toEqual([1, 2, 3])
25
+ expect(result).not.toBe(set)
26
+ expect(result).toEqual(set)
45
27
  })
46
28
  })
47
29
 
48
- describe('diffSets', () => {
49
- it('should detect added elements', () => {
50
- const prev = new Set(['a', 'b'])
51
- const next = new Set(['a', 'b', 'c'])
30
+ describe('diffSets (SU)', () => {
31
+ it('[SU2] reports added and removed elements, with only the populated keys', () => {
32
+ expect(diffSets(new Set(['a', 'b']), new Set(['a', 'b', 'c']))).toEqual({
33
+ added: new Set(['c']),
34
+ })
52
35
 
53
- const result = diffSets(prev, next)
36
+ expect(diffSets(new Set(['a', 'b', 'c']), new Set(['a', 'b']))).toEqual({
37
+ removed: new Set(['c']),
38
+ })
54
39
 
55
- expect(result?.added).toBeDefined()
56
- expect(result?.removed).toBeUndefined()
57
- expect(Array.from(result!.added!)).toEqual(['c'])
40
+ expect(diffSets(new Set(['a', 'b']), new Set(['b', 'c']))).toEqual({
41
+ added: new Set(['c']),
42
+ removed: new Set(['a']),
43
+ })
58
44
  })
59
45
 
60
- it('should detect removed elements', () => {
61
- const prev = new Set(['a', 'b', 'c'])
62
- const next = new Set(['a', 'b'])
63
-
64
- const result = diffSets(prev, next)
65
-
66
- expect(result?.removed).toBeDefined()
67
- expect(result?.added).toBeUndefined()
68
- expect(Array.from(result!.removed!)).toEqual(['c'])
46
+ it('[SU2] returns undefined when the sets have the same members', () => {
47
+ expect(diffSets(new Set(['a', 'b', 'c']), new Set(['a', 'b', 'c']))).toBeUndefined()
48
+ expect(diffSets(new Set(), new Set())).toBeUndefined()
69
49
  })
70
50
 
71
- it('should detect both added and removed elements', () => {
72
- const prev = new Set(['a', 'b'])
73
- const next = new Set(['b', 'c'])
74
-
75
- const result = diffSets(prev, next)
76
-
77
- expect(result?.added).toBeDefined()
78
- expect(result?.removed).toBeDefined()
79
- expect(Array.from(result!.added!)).toEqual(['c'])
80
- expect(Array.from(result!.removed!)).toEqual(['a'])
81
- })
82
-
83
- it('should return undefined when sets are identical', () => {
84
- const prev = new Set(['a', 'b', 'c'])
85
- const next = new Set(['a', 'b', 'c'])
86
-
87
- const result = diffSets(prev, next)
88
-
89
- expect(result).toBeUndefined()
90
- })
91
-
92
- it('should handle object references correctly', () => {
51
+ it('[SU2] compares object members by reference', () => {
93
52
  const obj1 = { id: 1 }
94
53
  const obj2 = { id: 2 }
95
54
  const obj3 = { id: 3 }
96
55
 
97
- const prev = new Set([obj1, obj2])
98
- const next = new Set([obj2, obj3])
99
-
100
- const result = diffSets(prev, next)
56
+ expect(diffSets(new Set([obj1, obj2]), new Set([obj2, obj3]))).toEqual({
57
+ added: new Set([obj3]),
58
+ removed: new Set([obj1]),
59
+ })
101
60
 
102
- expect(result?.added?.has(obj3)).toBe(true)
103
- expect(result?.removed?.has(obj1)).toBe(true)
61
+ // structurally equal but distinct objects are different members
62
+ expect(diffSets(new Set([{ id: 1 }]), new Set([{ id: 1 }]))).toBeDefined()
104
63
  })
105
64
  })
@@ -1,75 +0,0 @@
1
- import { createMigrationSequence } from '../migrate'
2
-
3
- describe(createMigrationSequence, () => {
4
- it('allows dependsOn to be deferred', () => {
5
- expect(
6
- createMigrationSequence({
7
- sequenceId: 'foo',
8
- retroactive: false,
9
- sequence: [{ dependsOn: ['bar/1'] }],
10
- }).sequence.length
11
- ).toBe(0)
12
-
13
- const result = createMigrationSequence({
14
- sequenceId: 'foo',
15
- retroactive: false,
16
- sequence: [
17
- {
18
- id: 'foo/1',
19
- scope: 'record',
20
- up() {
21
- // noop
22
- },
23
- },
24
- { dependsOn: ['bar/1'] },
25
- ],
26
- })
27
-
28
- expect(result.sequence.length).toBe(1)
29
- expect(result.sequence[0].dependsOn?.length).toBeFalsy()
30
-
31
- const result2 = createMigrationSequence({
32
- sequenceId: 'foo',
33
- retroactive: false,
34
- sequence: [
35
- { dependsOn: ['bar/1'] },
36
- {
37
- id: 'foo/1',
38
- scope: 'record',
39
- up() {
40
- // noop
41
- },
42
- },
43
- ],
44
- })
45
-
46
- expect(result2.sequence.length).toBe(1)
47
- expect(result2.sequence[0].dependsOn).toEqual(['bar/1'])
48
-
49
- const result3 = createMigrationSequence({
50
- sequenceId: 'foo',
51
- retroactive: false,
52
- sequence: [
53
- {
54
- id: 'foo/1',
55
- scope: 'record',
56
- up() {
57
- // noop
58
- },
59
- },
60
- { dependsOn: ['bar/1'] },
61
- {
62
- id: 'foo/2',
63
- scope: 'record',
64
- up() {
65
- // noop
66
- },
67
- },
68
- ],
69
- })
70
-
71
- expect(result3.sequence.length).toBe(2)
72
- expect(result3.sequence[0].dependsOn?.length).toBeFalsy()
73
- expect(result3.sequence[1].dependsOn).toEqual(['bar/1'])
74
- })
75
- })
@@ -1,166 +0,0 @@
1
- import { MigrationSequence, createMigrationSequence } from '../migrate'
2
- import { StoreSchema } from '../StoreSchema'
3
-
4
- describe('dependsOn', () => {
5
- it('requires the depended on ids to be present', () => {
6
- expect(() => {
7
- StoreSchema.create(
8
- {},
9
- {
10
- migrations: [
11
- {
12
- sequenceId: 'foo',
13
- retroactive: false,
14
- sequence: [
15
- {
16
- id: 'foo/1',
17
- dependsOn: ['bar/1'],
18
- scope: 'record',
19
- up() {
20
- // noop
21
- },
22
- },
23
- ],
24
- },
25
- ],
26
- }
27
- )
28
- }).toThrowErrorMatchingInlineSnapshot(
29
- `[Error: Migration 'foo/1' depends on missing migration 'bar/1']`
30
- )
31
- })
32
-
33
- it('makes sure the migrations are sorted', () => {
34
- const foo: MigrationSequence = {
35
- sequenceId: 'foo',
36
- retroactive: false,
37
- sequence: [
38
- {
39
- id: 'foo/1',
40
- dependsOn: ['bar/1'],
41
- scope: 'record',
42
- up() {
43
- // noop
44
- },
45
- },
46
- ],
47
- }
48
- const bar: MigrationSequence = {
49
- sequenceId: 'bar',
50
- retroactive: false,
51
- sequence: [
52
- {
53
- id: 'bar/1',
54
- scope: 'record',
55
- up() {
56
- // noop
57
- },
58
- },
59
- ],
60
- }
61
- const s = StoreSchema.create(
62
- {},
63
- {
64
- migrations: [foo, bar],
65
- }
66
- )
67
- const s2 = StoreSchema.create(
68
- {},
69
- {
70
- migrations: [bar, foo],
71
- }
72
- )
73
-
74
- expect(s.sortedMigrations.map((s) => s.id)).toMatchInlineSnapshot(`
75
- [
76
- "bar/1",
77
- "foo/1",
78
- ]
79
- `)
80
- expect(s2.sortedMigrations).toEqual(s.sortedMigrations)
81
- })
82
- })
83
-
84
- describe('standalone dependsOn', () => {
85
- it('requires the depended on ids to be present', () => {
86
- expect(() => {
87
- StoreSchema.create(
88
- {},
89
- {
90
- migrations: [
91
- createMigrationSequence({
92
- sequenceId: 'foo',
93
- retroactive: false,
94
- sequence: [
95
- {
96
- dependsOn: ['bar/1'],
97
- },
98
- {
99
- id: 'foo/1',
100
- scope: 'record',
101
- up() {
102
- // noop
103
- },
104
- },
105
- ],
106
- }),
107
- ],
108
- }
109
- )
110
- }).toThrowErrorMatchingInlineSnapshot(
111
- `[Error: Migration 'foo/1' depends on missing migration 'bar/1']`
112
- )
113
- })
114
-
115
- it('makes sure the migrations are sorted', () => {
116
- const foo: MigrationSequence = createMigrationSequence({
117
- sequenceId: 'foo',
118
- retroactive: false,
119
- sequence: [
120
- {
121
- dependsOn: ['bar/1'],
122
- },
123
- {
124
- id: 'foo/1',
125
- scope: 'record',
126
- up() {
127
- // noop
128
- },
129
- },
130
- ],
131
- })
132
- const bar: MigrationSequence = createMigrationSequence({
133
- sequenceId: 'bar',
134
- retroactive: false,
135
- sequence: [
136
- {
137
- id: 'bar/1',
138
- scope: 'record',
139
- up() {
140
- // noop
141
- },
142
- },
143
- ],
144
- })
145
- const s = StoreSchema.create(
146
- {},
147
- {
148
- migrations: [foo, bar],
149
- }
150
- )
151
- const s2 = StoreSchema.create(
152
- {},
153
- {
154
- migrations: [bar, foo],
155
- }
156
- )
157
-
158
- expect(s.sortedMigrations.map((s) => s.id)).toMatchInlineSnapshot(`
159
- [
160
- "bar/1",
161
- "foo/1",
162
- ]
163
- `)
164
- expect(s2.sortedMigrations).toEqual(s.sortedMigrations)
165
- })
166
- })
@@ -1,121 +0,0 @@
1
- import { MigrationSequence } from '../migrate'
2
- import { SerializedSchemaV2, StoreSchema } from '../StoreSchema'
3
-
4
- const mockSequence = ({
5
- id,
6
- retroactive,
7
- versions,
8
- }: {
9
- id: string
10
- retroactive: boolean
11
- versions: number
12
- }) =>
13
- ({
14
- sequenceId: id,
15
- retroactive,
16
- sequence: new Array(versions).fill(0).map((_, i) => ({
17
- id: `${id}/${i + 1}`,
18
- scope: 'record',
19
- up() {
20
- // noop
21
- },
22
- })),
23
- }) satisfies MigrationSequence
24
-
25
- function getMigrationsBetween(
26
- serialized: SerializedSchemaV2['sequences'],
27
- current: MigrationSequence[]
28
- ) {
29
- const schema = StoreSchema.create({}, { migrations: current })
30
- const ms = schema.getMigrationsSince({ schemaVersion: 2, sequences: serialized })
31
- if (!ms.ok) {
32
- throw new Error('Expected migrations to be found')
33
- }
34
- return ms.value.map((m) => m.id)
35
- }
36
-
37
- describe('getMigrationsSince', () => {
38
- it('includes migrations from new migration sequences with retroactive: true', () => {
39
- const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
40
- const bar = mockSequence({ id: 'bar', retroactive: true, versions: 3 })
41
-
42
- const ids = getMigrationsBetween({}, [foo, bar])
43
- const foos = ids.filter((id) => id.startsWith('foo'))
44
- const bars = ids.filter((id) => id.startsWith('bar'))
45
-
46
- expect(foos).toEqual(['foo/1', 'foo/2'])
47
- expect(bars).toEqual(['bar/1', 'bar/2', 'bar/3'])
48
- })
49
-
50
- it('does not include migrations from new migration sequences with retroactive: false', () => {
51
- const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
52
- const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
53
-
54
- const ids = getMigrationsBetween({}, [foo, bar])
55
- const foos = ids.filter((id) => id.startsWith('foo'))
56
- const bars = ids.filter((id) => id.startsWith('bar'))
57
-
58
- expect(foos).toEqual(['foo/1', 'foo/2'])
59
- expect(bars).toEqual([])
60
- })
61
-
62
- it('returns the empty array if there are no overlapping sequences and new ones are retroactive: false', () => {
63
- const foo = mockSequence({ id: 'foo', retroactive: false, versions: 2 })
64
- const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
65
-
66
- const ids = getMigrationsBetween({}, [foo, bar])
67
- expect(ids).toEqual([])
68
- })
69
-
70
- it('if a sequence is present both before and now, unapplied migrations will be returned', () => {
71
- const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
72
- const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
73
- const ids = getMigrationsBetween({ foo: 1, bar: 1 }, [foo, bar])
74
-
75
- const foos = ids.filter((id) => id.startsWith('foo'))
76
- const bars = ids.filter((id) => id.startsWith('bar'))
77
-
78
- expect(foos).toEqual(['foo/2'])
79
- expect(bars).toEqual(['bar/2', 'bar/3'])
80
- })
81
-
82
- it('if a sequence has not changed the empty array will be returned', () => {
83
- const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
84
- const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
85
- const ids = getMigrationsBetween({ foo: 2, bar: 3 }, [foo, bar])
86
-
87
- expect(ids).toEqual([])
88
- })
89
-
90
- it('if a sequence starts with 0 all unapplied migrations will be returned', () => {
91
- const foo = mockSequence({ id: 'foo', retroactive: true, versions: 2 })
92
- const bar = mockSequence({ id: 'bar', retroactive: false, versions: 3 })
93
-
94
- const ids = getMigrationsBetween(
95
- {
96
- foo: 0,
97
- bar: 0,
98
- },
99
- [foo, bar]
100
- )
101
- const foos = ids.filter((id) => id.startsWith('foo'))
102
- const bars = ids.filter((id) => id.startsWith('bar'))
103
-
104
- expect(foos).toEqual(['foo/1', 'foo/2'])
105
- expect(bars).toEqual(['bar/1', 'bar/2', 'bar/3'])
106
- })
107
-
108
- it('if a sequence starts with 0 and has 0 new migrations, no migrations will be returned', () => {
109
- const foo = mockSequence({ id: 'foo', retroactive: true, versions: 0 })
110
- const bar = mockSequence({ id: 'bar', retroactive: false, versions: 0 })
111
-
112
- const ids = getMigrationsBetween(
113
- {
114
- foo: 0,
115
- bar: 0,
116
- },
117
- [foo, bar]
118
- )
119
- expect(ids).toEqual([])
120
- })
121
- })
@@ -1,118 +0,0 @@
1
- import { SerializedStore } from '../Store'
2
- import { testSchemaV0 } from './testSchema.v0'
3
- import { testSchemaV1 } from './testSchema.v1'
4
-
5
- const serializedV0Schenma = testSchemaV0.serialize()
6
- const serializedV1Schenma = testSchemaV1.serialize()
7
-
8
- test('serializedV0Schenma', () => {
9
- expect(serializedV0Schenma).toMatchInlineSnapshot(`
10
- {
11
- "schemaVersion": 2,
12
- "sequences": {},
13
- }
14
- `)
15
- })
16
-
17
- test('serializedV1Schenma', () => {
18
- expect(serializedV1Schenma).toMatchInlineSnapshot(`
19
- {
20
- "schemaVersion": 2,
21
- "sequences": {
22
- "com.tldraw.shape": 2,
23
- "com.tldraw.shape.oval": 1,
24
- "com.tldraw.shape.rectangle": 1,
25
- "com.tldraw.store": 1,
26
- "com.tldraw.user": 2,
27
- },
28
- }
29
- `)
30
- })
31
-
32
- test('unknown types fail', () => {
33
- expect(
34
- testSchemaV1.migratePersistedRecord(
35
- {
36
- id: 'whatevere',
37
- typeName: 'steve',
38
- } as any,
39
- serializedV0Schenma,
40
- 'up'
41
- )
42
- ).toMatchObject({
43
- type: 'error',
44
- })
45
-
46
- expect(
47
- testSchemaV1.migratePersistedRecord(
48
- {
49
- id: 'whatevere',
50
- typeName: 'jeff',
51
- } as any,
52
- serializedV0Schenma,
53
- 'down'
54
- )
55
- ).toMatchObject({
56
- type: 'error',
57
- })
58
- })
59
-
60
- test('migrating a whole store snapshot works', () => {
61
- const serializedStore: SerializedStore<any> = {
62
- 'user-1': {
63
- id: 'user-1',
64
- typeName: 'user',
65
- name: 'name',
66
- },
67
- 'shape-1': {
68
- id: 'shape-1',
69
- typeName: 'shape',
70
- x: 0,
71
- y: 0,
72
- type: 'rectangle',
73
- props: {
74
- width: 100,
75
- height: 100,
76
- },
77
- },
78
- 'org-1': {
79
- id: 'org-1',
80
- typeName: 'org',
81
- name: 'tldraw',
82
- },
83
- }
84
-
85
- const result = testSchemaV1.migrateStoreSnapshot({
86
- store: serializedStore,
87
- schema: serializedV0Schenma,
88
- })
89
-
90
- if (result.type !== 'success') {
91
- console.error(result)
92
- throw new Error('Migration failed')
93
- }
94
-
95
- expect(result.value).toEqual({
96
- 'shape-1': {
97
- id: 'shape-1',
98
- typeName: 'shape',
99
- x: 0,
100
- y: 0,
101
- type: 'rectangle',
102
- parentId: null,
103
- rotation: 0,
104
- props: {
105
- width: 100,
106
- height: 100,
107
- opacity: 1,
108
- },
109
- },
110
- 'user-1': {
111
- id: 'user-1',
112
- typeName: 'user',
113
- name: 'name',
114
- locale: 'en',
115
- phoneNumber: null,
116
- },
117
- })
118
- })