@tldraw/store 3.16.0-internal.a478398270c6 → 3.16.0-internal.f8b97f0c414f
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/README.md +13 -13
- package/dist-cjs/index.d.ts +10 -42
- package/dist-cjs/index.js +1 -2
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/RecordType.js +0 -16
- package/dist-cjs/lib/RecordType.js.map +2 -2
- package/dist-cjs/lib/RecordsDiff.js +3 -3
- package/dist-cjs/lib/RecordsDiff.js.map +2 -2
- package/dist-cjs/lib/Store.js +1 -20
- package/dist-cjs/lib/Store.js.map +2 -2
- package/dist-cjs/lib/StoreSchema.js +24 -8
- package/dist-cjs/lib/StoreSchema.js.map +3 -3
- package/dist-cjs/lib/migrate.js +57 -43
- package/dist-cjs/lib/migrate.js.map +2 -2
- package/dist-esm/index.d.mts +10 -42
- package/dist-esm/index.mjs +1 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/RecordType.mjs +0 -16
- package/dist-esm/lib/RecordType.mjs.map +2 -2
- package/dist-esm/lib/RecordsDiff.mjs +3 -3
- package/dist-esm/lib/RecordsDiff.mjs.map +2 -2
- package/dist-esm/lib/Store.mjs +1 -20
- package/dist-esm/lib/Store.mjs.map +2 -2
- package/dist-esm/lib/StoreSchema.mjs +24 -8
- package/dist-esm/lib/StoreSchema.mjs.map +3 -3
- package/dist-esm/lib/migrate.mjs +57 -43
- package/dist-esm/lib/migrate.mjs.map +2 -2
- package/package.json +12 -19
- package/src/index.ts +0 -1
- package/src/lib/RecordType.ts +0 -17
- package/src/lib/RecordsDiff.ts +9 -3
- package/src/lib/Store.ts +1 -22
- package/src/lib/StoreSchema.ts +33 -8
- package/src/lib/migrate.ts +106 -57
- package/src/lib/test/AtomMap.test.ts +2 -1
- package/src/lib/test/dependsOn.test.ts +2 -2
- package/src/lib/test/migrationCaching.test.ts +209 -0
- package/src/lib/test/recordStore.test.ts +40 -37
- package/src/lib/test/sortMigrations.test.ts +36 -4
- package/src/lib/test/validateMigrations.test.ts +8 -8
- package/src/lib/test/defineMigrations.test.ts +0 -232
package/README.md
CHANGED
|
@@ -40,11 +40,11 @@ const store = new RecordStore<Book | Author>()
|
|
|
40
40
|
Then you can create records, add them to the store, update, and remove them.
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
const tolkeinId = Author.
|
|
43
|
+
const tolkeinId = Author.createId('tolkein')
|
|
44
44
|
|
|
45
45
|
store.put([
|
|
46
46
|
Author.create({
|
|
47
|
-
id:
|
|
47
|
+
id: tolkeinId,
|
|
48
48
|
name: 'J.R.R Tolkein',
|
|
49
49
|
}),
|
|
50
50
|
])
|
|
@@ -77,7 +77,7 @@ Add some records to the store. It's an error if they already exist.
|
|
|
77
77
|
```ts
|
|
78
78
|
const record = Author.create({
|
|
79
79
|
name: 'J.R.R Tolkein',
|
|
80
|
-
id: Author.
|
|
80
|
+
id: Author.createId('tolkein'),
|
|
81
81
|
})
|
|
82
82
|
|
|
83
83
|
store.put([record])
|
|
@@ -88,7 +88,7 @@ store.put([record])
|
|
|
88
88
|
Update a record. To update multiple records at once, use the `update` method of the `TypedRecordStore` class.
|
|
89
89
|
|
|
90
90
|
```ts
|
|
91
|
-
const id = Author.
|
|
91
|
+
const id = Author.createId('tolkein')
|
|
92
92
|
|
|
93
93
|
store.update(id, (r) => ({ ...r, name: 'Jimmy Tolks' }))
|
|
94
94
|
```
|
|
@@ -98,7 +98,7 @@ store.update(id, (r) => ({ ...r, name: 'Jimmy Tolks' }))
|
|
|
98
98
|
Remove some records from the store via their ids.
|
|
99
99
|
|
|
100
100
|
```ts
|
|
101
|
-
const id = Author.
|
|
101
|
+
const id = Author.createId('tolkein')
|
|
102
102
|
|
|
103
103
|
store.remove([id])
|
|
104
104
|
```
|
|
@@ -108,7 +108,7 @@ store.remove([id])
|
|
|
108
108
|
Get the value of a store record by its id.
|
|
109
109
|
|
|
110
110
|
```ts
|
|
111
|
-
const id = Author.
|
|
111
|
+
const id = Author.createId('tolkein')
|
|
112
112
|
|
|
113
113
|
const result = store.get(id)
|
|
114
114
|
```
|
|
@@ -134,7 +134,7 @@ store.clear()
|
|
|
134
134
|
Get whether the record store has an record stored under the given id.
|
|
135
135
|
|
|
136
136
|
```ts
|
|
137
|
-
const id = Author.
|
|
137
|
+
const id = Author.createId('tolkein')
|
|
138
138
|
|
|
139
139
|
const result = store.has(id)
|
|
140
140
|
```
|
|
@@ -163,7 +163,7 @@ store.deserialize(serialized)
|
|
|
163
163
|
|
|
164
164
|
### `listen(listener: ((entry: HistoryEntry) => void): () => void`
|
|
165
165
|
|
|
166
|
-
Add a new listener to the store The store will call the function each time the history changes. Returns a function to remove the listener.
|
|
166
|
+
Add a new listener to the store. The store will call the function each time the history changes. Returns a function to remove the listener.
|
|
167
167
|
|
|
168
168
|
```ts
|
|
169
169
|
store.listen((entry) => doSomethingWith(entry))
|
|
@@ -227,12 +227,12 @@ Create an Id for a record of this type.
|
|
|
227
227
|
const id = recordType.createId()
|
|
228
228
|
```
|
|
229
229
|
|
|
230
|
-
### `
|
|
230
|
+
### `createId(id: string): ID<R>`
|
|
231
231
|
|
|
232
232
|
Create a custom Id for a record of this type.
|
|
233
233
|
|
|
234
234
|
```ts
|
|
235
|
-
const id = recordType.
|
|
235
|
+
const id = recordType.createId('tolkein')
|
|
236
236
|
```
|
|
237
237
|
|
|
238
238
|
### `isInstance`
|
|
@@ -251,7 +251,7 @@ const result2 = recordType.isInstance(someOtherRecord) // false
|
|
|
251
251
|
Check if a value is an id for a record of this type.
|
|
252
252
|
|
|
253
253
|
```ts
|
|
254
|
-
const id = recordType.
|
|
254
|
+
const id = recordType.createId('tolkein')
|
|
255
255
|
|
|
256
256
|
const result1 = recordType.isId(id) // true
|
|
257
257
|
const result2 = recordType.isId(someOtherId) // false
|
|
@@ -300,7 +300,7 @@ const recordType = createRecordType('author'))
|
|
|
300
300
|
A helper used to assert that a value is an id for a record of a given type.
|
|
301
301
|
|
|
302
302
|
```ts
|
|
303
|
-
const id = recordType.
|
|
303
|
+
const id = recordType.createId('tolkein')
|
|
304
304
|
|
|
305
305
|
assertIdType(id, recordType)
|
|
306
306
|
```
|
|
@@ -314,7 +314,7 @@ assertIdType(id, recordType)
|
|
|
314
314
|
A type used to represent a record's id.
|
|
315
315
|
|
|
316
316
|
```ts
|
|
317
|
-
const id: ID<Author> = Author.
|
|
317
|
+
const id: ID<Author> = Author.createId('tolkein')
|
|
318
318
|
```
|
|
319
319
|
|
|
320
320
|
### `BaseRecord`
|
package/dist-cjs/index.d.ts
CHANGED
|
@@ -149,18 +149,6 @@ export declare function createRecordType<R extends UnknownRecord>(typeName: R['t
|
|
|
149
149
|
validator?: StoreValidator<R>;
|
|
150
150
|
}): RecordType<R, keyof Omit<R, 'id' | 'typeName'>>;
|
|
151
151
|
|
|
152
|
-
/**
|
|
153
|
-
* @public
|
|
154
|
-
* @deprecated use `createShapePropsMigrationSequence` instead. See [the docs](https://tldraw.dev/docs/persistence#Updating-legacy-shape-migrations-defineMigrations) for how to migrate.
|
|
155
|
-
*/
|
|
156
|
-
export declare function defineMigrations(opts: {
|
|
157
|
-
currentVersion?: number;
|
|
158
|
-
firstVersion?: number;
|
|
159
|
-
migrators?: Record<number, LegacyMigration>;
|
|
160
|
-
subTypeKey?: string;
|
|
161
|
-
subTypeMigrations?: Record<string, LegacyBaseMigrationsInfo>;
|
|
162
|
-
}): LegacyMigrations;
|
|
163
|
-
|
|
164
152
|
/**
|
|
165
153
|
* Freeze an object when in development mode. Copied from
|
|
166
154
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
|
|
@@ -378,20 +366,6 @@ export declare class RecordType<R extends UnknownRecord, RequiredProperties exte
|
|
|
378
366
|
* @public
|
|
379
367
|
*/
|
|
380
368
|
createId(customUniquePart?: string): IdOf<R>;
|
|
381
|
-
/**
|
|
382
|
-
* Create a new ID for this record type based on the given ID.
|
|
383
|
-
*
|
|
384
|
-
* @example
|
|
385
|
-
*
|
|
386
|
-
* ```ts
|
|
387
|
-
* const id = recordType.createCustomId('myId')
|
|
388
|
-
* ```
|
|
389
|
-
*
|
|
390
|
-
* @deprecated - Use `createId` instead.
|
|
391
|
-
* @param id - The ID to base the new ID on.
|
|
392
|
-
* @returns The new ID.
|
|
393
|
-
*/
|
|
394
|
-
createCustomId(id: string): IdOf<R>;
|
|
395
369
|
/**
|
|
396
370
|
* Takes an id like `user:123` and returns the part after the colon `123`
|
|
397
371
|
*
|
|
@@ -500,10 +474,13 @@ export declare type SerializedStore<R extends UnknownRecord> = Record<IdOf<R>, R
|
|
|
500
474
|
* Squash a collection of diffs into a single diff.
|
|
501
475
|
*
|
|
502
476
|
* @param diffs - An array of diffs to squash.
|
|
477
|
+
* @param options - An optional object with a `mutateFirstDiff` property. If `mutateFirstDiff` is true, the first diff in the array will be mutated in-place.
|
|
503
478
|
* @returns A single diff that represents the squashed diffs.
|
|
504
479
|
* @public
|
|
505
480
|
*/
|
|
506
|
-
export declare function squashRecordDiffs<T extends UnknownRecord>(diffs: RecordsDiff<T>[]
|
|
481
|
+
export declare function squashRecordDiffs<T extends UnknownRecord>(diffs: RecordsDiff<T>[], options?: {
|
|
482
|
+
mutateFirstDiff?: boolean;
|
|
483
|
+
}): RecordsDiff<T>;
|
|
507
484
|
|
|
508
485
|
/* Excluded from this release type: squashRecordDiffsMutable */
|
|
509
486
|
|
|
@@ -627,15 +604,11 @@ export declare class Store<R extends UnknownRecord = UnknownRecord, Props = unkn
|
|
|
627
604
|
* @public
|
|
628
605
|
*/
|
|
629
606
|
getStoreSnapshot(scope?: 'all' | RecordScope): StoreSnapshot<R>;
|
|
630
|
-
/**
|
|
631
|
-
* @deprecated use `getSnapshot` from the 'tldraw' package instead.
|
|
632
|
-
*/
|
|
633
|
-
getSnapshot(scope?: 'all' | RecordScope): StoreSnapshot<R>;
|
|
634
607
|
/**
|
|
635
608
|
* Migrate a serialized snapshot of the store and its schema.
|
|
636
609
|
*
|
|
637
610
|
* ```ts
|
|
638
|
-
* const snapshot = store.
|
|
611
|
+
* const snapshot = store.getStoreSnapshot()
|
|
639
612
|
* store.migrateSnapshot(snapshot)
|
|
640
613
|
* ```
|
|
641
614
|
*
|
|
@@ -655,11 +628,6 @@ export declare class Store<R extends UnknownRecord = UnknownRecord, Props = unkn
|
|
|
655
628
|
* @public
|
|
656
629
|
*/
|
|
657
630
|
loadStoreSnapshot(snapshot: StoreSnapshot<R>): void;
|
|
658
|
-
/**
|
|
659
|
-
* @public
|
|
660
|
-
* @deprecated use `loadSnapshot` from the 'tldraw' package instead.
|
|
661
|
-
*/
|
|
662
|
-
loadSnapshot(snapshot: StoreSnapshot<R>): void;
|
|
663
631
|
/**
|
|
664
632
|
* Get an array of all values in the store.
|
|
665
633
|
*
|
|
@@ -892,17 +860,17 @@ export declare class StoreSchema<R extends UnknownRecord, P = unknown> {
|
|
|
892
860
|
}, options?: StoreSchemaOptions<R, P>): StoreSchema<R, P>;
|
|
893
861
|
readonly migrations: Record<string, MigrationSequence>;
|
|
894
862
|
readonly sortedMigrations: readonly Migration[];
|
|
863
|
+
private readonly migrationCache;
|
|
895
864
|
private constructor();
|
|
896
865
|
validateRecord(store: Store<R>, record: R, phase: 'createRecord' | 'initialize' | 'tests' | 'updateRecord', recordBefore: null | R): R;
|
|
897
866
|
getMigrationsSince(persistedSchema: SerializedSchema): Result<Migration[], string>;
|
|
898
867
|
migratePersistedRecord(record: R, persistedSchema: SerializedSchema, direction?: 'down' | 'up'): MigrationResult<R>;
|
|
899
|
-
migrateStoreSnapshot(snapshot: StoreSnapshot<R
|
|
868
|
+
migrateStoreSnapshot(snapshot: StoreSnapshot<R>, opts?: {
|
|
869
|
+
mutateInputStore?: boolean;
|
|
870
|
+
}): MigrationResult<SerializedStore<R>>;
|
|
900
871
|
/* Excluded from this release type: createIntegrityChecker */
|
|
901
872
|
serialize(): SerializedSchemaV2;
|
|
902
|
-
|
|
903
|
-
* @deprecated This is only here for legacy reasons, don't use it unless you have david's blessing!
|
|
904
|
-
*/
|
|
905
|
-
serializeEarliestVersion(): SerializedSchema;
|
|
873
|
+
/* Excluded from this release type: serializeEarliestVersion */
|
|
906
874
|
/* Excluded from this release type: getType */
|
|
907
875
|
}
|
|
908
876
|
|
package/dist-cjs/index.js
CHANGED
|
@@ -33,7 +33,6 @@ __export(index_exports, {
|
|
|
33
33
|
createMigrationSequence: () => import_migrate.createMigrationSequence,
|
|
34
34
|
createRecordMigrationSequence: () => import_migrate.createRecordMigrationSequence,
|
|
35
35
|
createRecordType: () => import_RecordType.createRecordType,
|
|
36
|
-
defineMigrations: () => import_migrate.defineMigrations,
|
|
37
36
|
devFreeze: () => import_devFreeze.devFreeze,
|
|
38
37
|
isRecordsDiffEmpty: () => import_RecordsDiff.isRecordsDiffEmpty,
|
|
39
38
|
parseMigrationId: () => import_migrate.parseMigrationId,
|
|
@@ -55,7 +54,7 @@ var import_StoreSchema = require("./lib/StoreSchema");
|
|
|
55
54
|
var import_StoreSideEffects = require("./lib/StoreSideEffects");
|
|
56
55
|
(0, import_utils.registerTldrawLibraryVersion)(
|
|
57
56
|
"@tldraw/store",
|
|
58
|
-
"3.16.0-internal.
|
|
57
|
+
"3.16.0-internal.f8b97f0c414f",
|
|
59
58
|
"cjs"
|
|
60
59
|
);
|
|
61
60
|
//# sourceMappingURL=index.js.map
|
package/dist-cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\nexport { AtomMap } from './lib/AtomMap'\nexport type { BaseRecord, IdOf, RecordId, UnknownRecord } from './lib/BaseRecord'\nexport { devFreeze } from './lib/devFreeze'\nexport { type QueryExpression, type QueryValueMatcher } from './lib/executeQuery'\nexport { IncrementalSetConstructor } from './lib/IncrementalSetConstructor'\nexport {\n\tcreateMigrationIds,\n\tcreateMigrationSequence,\n\tcreateRecordMigrationSequence,\n\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA
|
|
4
|
+
"sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\nexport { AtomMap } from './lib/AtomMap'\nexport type { BaseRecord, IdOf, RecordId, UnknownRecord } from './lib/BaseRecord'\nexport { devFreeze } from './lib/devFreeze'\nexport { type QueryExpression, type QueryValueMatcher } from './lib/executeQuery'\nexport { IncrementalSetConstructor } from './lib/IncrementalSetConstructor'\nexport {\n\tcreateMigrationIds,\n\tcreateMigrationSequence,\n\tcreateRecordMigrationSequence,\n\tMigrationFailureReason,\n\tparseMigrationId,\n\ttype LegacyBaseMigrationsInfo,\n\ttype LegacyMigration,\n\ttype LegacyMigrations,\n\ttype Migration,\n\ttype MigrationId,\n\ttype MigrationResult,\n\ttype MigrationSequence,\n\ttype StandaloneDependsOn,\n} from './lib/migrate'\nexport {\n\tcreateEmptyRecordsDiff,\n\tisRecordsDiffEmpty,\n\treverseRecordsDiff,\n\tsquashRecordDiffs,\n\tsquashRecordDiffsMutable,\n\ttype RecordsDiff,\n} from './lib/RecordsDiff'\nexport { assertIdType, createRecordType, RecordType, type RecordScope } from './lib/RecordType'\nexport {\n\tcreateComputedCache,\n\tStore,\n\ttype ChangeSource,\n\ttype CollectionDiff,\n\ttype ComputedCache,\n\ttype CreateComputedCacheOpts,\n\ttype HistoryEntry,\n\ttype RecordFromId,\n\ttype SerializedStore,\n\ttype StoreError,\n\ttype StoreListener,\n\ttype StoreListenerFilters,\n\ttype StoreObject,\n\ttype StoreObjectRecordType,\n\ttype StoreRecord,\n\ttype StoreSnapshot,\n\ttype StoreValidator,\n\ttype StoreValidators,\n} from './lib/Store'\nexport { StoreQueries, type RSIndex, type RSIndexDiff, type RSIndexMap } from './lib/StoreQueries'\nexport { StoreSchema, type StoreValidationFailure } from './lib/StoreSchema'\nexport type {\n\tSerializedSchema,\n\tSerializedSchemaV1,\n\tSerializedSchemaV2,\n\tStoreSchemaOptions,\n} from './lib/StoreSchema'\nexport {\n\tStoreSideEffects,\n\ttype StoreAfterChangeHandler,\n\ttype StoreAfterCreateHandler,\n\ttype StoreAfterDeleteHandler,\n\ttype StoreBeforeChangeHandler,\n\ttype StoreBeforeCreateHandler,\n\ttype StoreBeforeDeleteHandler,\n\ttype StoreOperationCompleteHandler,\n} from './lib/StoreSideEffects'\n\nregisterTldrawLibraryVersion(\n\t(globalThis as any).TLDRAW_LIBRARY_NAME,\n\t(globalThis as any).TLDRAW_LIBRARY_VERSION,\n\t(globalThis as any).TLDRAW_LIBRARY_MODULES\n)\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA6C;AAC7C,qBAAwB;AAExB,uBAA0B;AAE1B,uCAA0C;AAC1C,qBAcO;AACP,yBAOO;AACP,wBAA6E;AAC7E,mBAmBO;AACP,0BAA8E;AAC9E,yBAAyD;AAOzD,8BASO;AAAA,IAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -88,22 +88,6 @@ class RecordType {
|
|
|
88
88
|
createId(customUniquePart) {
|
|
89
89
|
return this.typeName + ":" + (customUniquePart ?? (0, import_utils.uniqueId)());
|
|
90
90
|
}
|
|
91
|
-
/**
|
|
92
|
-
* Create a new ID for this record type based on the given ID.
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
*
|
|
96
|
-
* ```ts
|
|
97
|
-
* const id = recordType.createCustomId('myId')
|
|
98
|
-
* ```
|
|
99
|
-
*
|
|
100
|
-
* @deprecated - Use `createId` instead.
|
|
101
|
-
* @param id - The ID to base the new ID on.
|
|
102
|
-
* @returns The new ID.
|
|
103
|
-
*/
|
|
104
|
-
createCustomId(id) {
|
|
105
|
-
return this.typeName + ":" + id;
|
|
106
|
-
}
|
|
107
91
|
/**
|
|
108
92
|
* Takes an id like `user:123` and returns the part after the colon `123`
|
|
109
93
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/RecordType.ts"],
|
|
4
|
-
"sourcesContent": ["import { Expand, objectMapEntries, structuredClone, uniqueId } from '@tldraw/utils'\nimport { IdOf, UnknownRecord } from './BaseRecord'\nimport { StoreValidator } from './Store'\n\nexport type RecordTypeRecord<R extends RecordType<any, any>> = ReturnType<R['create']>\n\n/**\n * Defines the scope of the record\n *\n * session: The record belongs to a single instance of the store. It should not be synced, and any persistence logic should 'de-instance-ize' the record before persisting it, and apply the reverse when rehydrating.\n * document: The record is persisted and synced. It is available to all store instances.\n * presence: The record belongs to a single instance of the store. It may be synced to other instances, but other instances should not make changes to it. It should not be persisted.\n *\n * @public\n * */\nexport type RecordScope = 'session' | 'document' | 'presence'\n\n/**\n * A record type is a type that can be stored in a record store. It is created with\n * `createRecordType`.\n *\n * @public\n */\nexport class RecordType<\n\tR extends UnknownRecord,\n\tRequiredProperties extends keyof Omit<R, 'id' | 'typeName'>,\n> {\n\treadonly createDefaultProperties: () => Exclude<Omit<R, 'id' | 'typeName'>, RequiredProperties>\n\treadonly validator: StoreValidator<R>\n\treadonly ephemeralKeys?: { readonly [K in Exclude<keyof R, 'id' | 'typeName'>]: boolean }\n\treadonly ephemeralKeySet: ReadonlySet<string>\n\treadonly scope: RecordScope\n\n\tconstructor(\n\t\t/**\n\t\t * The unique type associated with this record.\n\t\t *\n\t\t * @public\n\t\t * @readonly\n\t\t */\n\t\tpublic readonly typeName: R['typeName'],\n\t\tconfig: {\n\t\t\t// eslint-disable-next-line @typescript-eslint/method-signature-style\n\t\t\treadonly createDefaultProperties: () => Exclude<\n\t\t\t\tOmit<R, 'id' | 'typeName'>,\n\t\t\t\tRequiredProperties\n\t\t\t>\n\t\t\treadonly validator?: StoreValidator<R>\n\t\t\treadonly scope?: RecordScope\n\t\t\treadonly ephemeralKeys?: { readonly [K in Exclude<keyof R, 'id' | 'typeName'>]: boolean }\n\t\t}\n\t) {\n\t\tthis.createDefaultProperties = config.createDefaultProperties\n\t\tthis.validator = config.validator ?? { validate: (r: unknown) => r as R }\n\t\tthis.scope = config.scope ?? 'document'\n\t\tthis.ephemeralKeys = config.ephemeralKeys\n\n\t\tconst ephemeralKeySet = new Set<string>()\n\t\tif (config.ephemeralKeys) {\n\t\t\tfor (const [key, isEphemeral] of objectMapEntries(config.ephemeralKeys)) {\n\t\t\t\tif (isEphemeral) ephemeralKeySet.add(key)\n\t\t\t}\n\t\t}\n\t\tthis.ephemeralKeySet = ephemeralKeySet\n\t}\n\n\t/**\n\t * Create a new record of this type.\n\t *\n\t * @param properties - The properties of the record.\n\t * @returns The new record.\n\t */\n\tcreate(\n\t\tproperties: Expand<Pick<R, RequiredProperties> & Omit<Partial<R>, RequiredProperties>>\n\t): R {\n\t\tconst result = {\n\t\t\t...this.createDefaultProperties(),\n\t\t\tid: 'id' in properties ? properties.id : this.createId(),\n\t\t} as any\n\n\t\tfor (const [k, v] of Object.entries(properties)) {\n\t\t\tif (v !== undefined) {\n\t\t\t\tresult[k] = v\n\t\t\t}\n\t\t}\n\n\t\tresult.typeName = this.typeName\n\n\t\treturn result as R\n\t}\n\n\t/**\n\t * Clone a record of this type.\n\t *\n\t * @param record - The record to clone.\n\t * @returns The cloned record.\n\t * @public\n\t */\n\tclone(record: R): R {\n\t\treturn { ...structuredClone(record), id: this.createId() }\n\t}\n\n\t/**\n\t * Create a new ID for this record type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const id = recordType.createId()\n\t * ```\n\t *\n\t * @returns The new ID.\n\t * @public\n\t */\n\tcreateId(customUniquePart?: string): IdOf<R> {\n\t\treturn (this.typeName + ':' + (customUniquePart ?? uniqueId())) as IdOf<R>\n\t}\n\n\t/**\n\t *
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAoE;AAuB7D,MAAM,WAGX;AAAA,EAOD,YAOiB,UAChB,QAUC;AAXe;AAYhB,SAAK,0BAA0B,OAAO;AACtC,SAAK,YAAY,OAAO,aAAa,EAAE,UAAU,CAAC,MAAe,EAAO;AACxE,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,gBAAgB,OAAO;AAE5B,UAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAI,OAAO,eAAe;AACzB,iBAAW,CAAC,KAAK,WAAW,SAAK,+BAAiB,OAAO,aAAa,GAAG;AACxE,YAAI,YAAa,iBAAgB,IAAI,GAAG;AAAA,MACzC;AAAA,IACD;AACA,SAAK,kBAAkB;AAAA,EACxB;AAAA,EArCS;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyCT,OACC,YACI;AACJ,UAAM,SAAS;AAAA,MACd,GAAG,KAAK,wBAAwB;AAAA,MAChC,IAAI,QAAQ,aAAa,WAAW,KAAK,KAAK,SAAS;AAAA,IACxD;AAEA,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,UAAU,GAAG;AAChD,UAAI,MAAM,QAAW;AACpB,eAAO,CAAC,IAAI;AAAA,MACb;AAAA,IACD;AAEA,WAAO,WAAW,KAAK;AAEvB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAc;AACnB,WAAO,EAAE,OAAG,8BAAgB,MAAM,GAAG,IAAI,KAAK,SAAS,EAAE;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,SAAS,kBAAoC;AAC5C,WAAQ,KAAK,WAAW,OAAO,wBAAoB,uBAAS;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA
|
|
4
|
+
"sourcesContent": ["import { Expand, objectMapEntries, structuredClone, uniqueId } from '@tldraw/utils'\nimport { IdOf, UnknownRecord } from './BaseRecord'\nimport { StoreValidator } from './Store'\n\nexport type RecordTypeRecord<R extends RecordType<any, any>> = ReturnType<R['create']>\n\n/**\n * Defines the scope of the record\n *\n * session: The record belongs to a single instance of the store. It should not be synced, and any persistence logic should 'de-instance-ize' the record before persisting it, and apply the reverse when rehydrating.\n * document: The record is persisted and synced. It is available to all store instances.\n * presence: The record belongs to a single instance of the store. It may be synced to other instances, but other instances should not make changes to it. It should not be persisted.\n *\n * @public\n * */\nexport type RecordScope = 'session' | 'document' | 'presence'\n\n/**\n * A record type is a type that can be stored in a record store. It is created with\n * `createRecordType`.\n *\n * @public\n */\nexport class RecordType<\n\tR extends UnknownRecord,\n\tRequiredProperties extends keyof Omit<R, 'id' | 'typeName'>,\n> {\n\treadonly createDefaultProperties: () => Exclude<Omit<R, 'id' | 'typeName'>, RequiredProperties>\n\treadonly validator: StoreValidator<R>\n\treadonly ephemeralKeys?: { readonly [K in Exclude<keyof R, 'id' | 'typeName'>]: boolean }\n\treadonly ephemeralKeySet: ReadonlySet<string>\n\treadonly scope: RecordScope\n\n\tconstructor(\n\t\t/**\n\t\t * The unique type associated with this record.\n\t\t *\n\t\t * @public\n\t\t * @readonly\n\t\t */\n\t\tpublic readonly typeName: R['typeName'],\n\t\tconfig: {\n\t\t\t// eslint-disable-next-line @typescript-eslint/method-signature-style\n\t\t\treadonly createDefaultProperties: () => Exclude<\n\t\t\t\tOmit<R, 'id' | 'typeName'>,\n\t\t\t\tRequiredProperties\n\t\t\t>\n\t\t\treadonly validator?: StoreValidator<R>\n\t\t\treadonly scope?: RecordScope\n\t\t\treadonly ephemeralKeys?: { readonly [K in Exclude<keyof R, 'id' | 'typeName'>]: boolean }\n\t\t}\n\t) {\n\t\tthis.createDefaultProperties = config.createDefaultProperties\n\t\tthis.validator = config.validator ?? { validate: (r: unknown) => r as R }\n\t\tthis.scope = config.scope ?? 'document'\n\t\tthis.ephemeralKeys = config.ephemeralKeys\n\n\t\tconst ephemeralKeySet = new Set<string>()\n\t\tif (config.ephemeralKeys) {\n\t\t\tfor (const [key, isEphemeral] of objectMapEntries(config.ephemeralKeys)) {\n\t\t\t\tif (isEphemeral) ephemeralKeySet.add(key)\n\t\t\t}\n\t\t}\n\t\tthis.ephemeralKeySet = ephemeralKeySet\n\t}\n\n\t/**\n\t * Create a new record of this type.\n\t *\n\t * @param properties - The properties of the record.\n\t * @returns The new record.\n\t */\n\tcreate(\n\t\tproperties: Expand<Pick<R, RequiredProperties> & Omit<Partial<R>, RequiredProperties>>\n\t): R {\n\t\tconst result = {\n\t\t\t...this.createDefaultProperties(),\n\t\t\tid: 'id' in properties ? properties.id : this.createId(),\n\t\t} as any\n\n\t\tfor (const [k, v] of Object.entries(properties)) {\n\t\t\tif (v !== undefined) {\n\t\t\t\tresult[k] = v\n\t\t\t}\n\t\t}\n\n\t\tresult.typeName = this.typeName\n\n\t\treturn result as R\n\t}\n\n\t/**\n\t * Clone a record of this type.\n\t *\n\t * @param record - The record to clone.\n\t * @returns The cloned record.\n\t * @public\n\t */\n\tclone(record: R): R {\n\t\treturn { ...structuredClone(record), id: this.createId() }\n\t}\n\n\t/**\n\t * Create a new ID for this record type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const id = recordType.createId()\n\t * ```\n\t *\n\t * @returns The new ID.\n\t * @public\n\t */\n\tcreateId(customUniquePart?: string): IdOf<R> {\n\t\treturn (this.typeName + ':' + (customUniquePart ?? uniqueId())) as IdOf<R>\n\t}\n\n\t/**\n\t * Takes an id like `user:123` and returns the part after the colon `123`\n\t *\n\t * @param id - The id\n\t * @returns\n\t */\n\tparseId(id: IdOf<R>): string {\n\t\tif (!this.isId(id)) {\n\t\t\tthrow new Error(`ID \"${id}\" is not a valid ID for type \"${this.typeName}\"`)\n\t\t}\n\n\t\treturn id.slice(this.typeName.length + 1)\n\t}\n\n\t/**\n\t * Check whether a record is an instance of this record type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const result = recordType.isInstance(someRecord)\n\t * ```\n\t *\n\t * @param record - The record to check.\n\t * @returns Whether the record is an instance of this record type.\n\t */\n\tisInstance(record?: UnknownRecord): record is R {\n\t\treturn record?.typeName === this.typeName\n\t}\n\n\t/**\n\t * Check whether an id is an id of this type.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const result = recordType.isIn('someId')\n\t * ```\n\t *\n\t * @param id - The id to check.\n\t * @returns Whether the id is an id of this type.\n\t */\n\tisId(id?: string): id is IdOf<R> {\n\t\tif (!id) return false\n\t\tfor (let i = 0; i < this.typeName.length; i++) {\n\t\t\tif (id[i] !== this.typeName[i]) return false\n\t\t}\n\n\t\treturn id[this.typeName.length] === ':'\n\t}\n\n\t/**\n\t * Create a new RecordType that has the same type name as this RecordType and includes the given\n\t * default properties.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const authorType = createRecordType('author', () => ({ living: true }))\n\t * const deadAuthorType = authorType.withDefaultProperties({ living: false })\n\t * ```\n\t *\n\t * @param createDefaultProperties - A function that returns the default properties of the new RecordType.\n\t * @returns The new RecordType.\n\t */\n\twithDefaultProperties<DefaultProps extends Omit<Partial<R>, 'typeName' | 'id'>>(\n\t\tcreateDefaultProperties: () => DefaultProps\n\t): RecordType<R, Exclude<RequiredProperties, keyof DefaultProps>> {\n\t\treturn new RecordType<R, Exclude<RequiredProperties, keyof DefaultProps>>(this.typeName, {\n\t\t\tcreateDefaultProperties: createDefaultProperties as any,\n\t\t\tvalidator: this.validator,\n\t\t\tscope: this.scope,\n\t\t\tephemeralKeys: this.ephemeralKeys,\n\t\t})\n\t}\n\n\t/**\n\t * Check that the passed in record passes the validations for this type. Returns its input\n\t * correctly typed if it does, but throws an error otherwise.\n\t */\n\tvalidate(record: unknown, recordBefore?: R): R {\n\t\tif (recordBefore && this.validator.validateUsingKnownGoodVersion) {\n\t\t\treturn this.validator.validateUsingKnownGoodVersion(recordBefore, record)\n\t\t}\n\t\treturn this.validator.validate(record)\n\t}\n}\n\n/**\n * Create a record type.\n *\n * @example\n *\n * ```ts\n * const Book = createRecordType<Book>('book')\n * ```\n *\n * @param typeName - The name of the type to create.\n * @public\n */\nexport function createRecordType<R extends UnknownRecord>(\n\ttypeName: R['typeName'],\n\tconfig: {\n\t\tvalidator?: StoreValidator<R>\n\t\tscope: RecordScope\n\t\tephemeralKeys?: { readonly [K in Exclude<keyof R, 'id' | 'typeName'>]: boolean }\n\t}\n): RecordType<R, keyof Omit<R, 'id' | 'typeName'>> {\n\treturn new RecordType<R, keyof Omit<R, 'id' | 'typeName'>>(typeName, {\n\t\tcreateDefaultProperties: () => ({}) as any,\n\t\tvalidator: config.validator,\n\t\tscope: config.scope,\n\t\tephemeralKeys: config.ephemeralKeys,\n\t})\n}\n\n/**\n * Assert whether an id correspond to a record type.\n *\n * @example\n *\n * ```ts\n * assertIdType(myId, \"shape\")\n * ```\n *\n * @param id - The id to check.\n * @param type - The type of the record.\n * @public\n */\nexport function assertIdType<R extends UnknownRecord>(\n\tid: string | undefined,\n\ttype: RecordType<R, any>\n): asserts id is IdOf<R> {\n\tif (!id || !type.isId(id)) {\n\t\tthrow new Error(`string ${JSON.stringify(id)} is not a valid ${type.typeName} id`)\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAoE;AAuB7D,MAAM,WAGX;AAAA,EAOD,YAOiB,UAChB,QAUC;AAXe;AAYhB,SAAK,0BAA0B,OAAO;AACtC,SAAK,YAAY,OAAO,aAAa,EAAE,UAAU,CAAC,MAAe,EAAO;AACxE,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,gBAAgB,OAAO;AAE5B,UAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAI,OAAO,eAAe;AACzB,iBAAW,CAAC,KAAK,WAAW,SAAK,+BAAiB,OAAO,aAAa,GAAG;AACxE,YAAI,YAAa,iBAAgB,IAAI,GAAG;AAAA,MACzC;AAAA,IACD;AACA,SAAK,kBAAkB;AAAA,EACxB;AAAA,EArCS;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyCT,OACC,YACI;AACJ,UAAM,SAAS;AAAA,MACd,GAAG,KAAK,wBAAwB;AAAA,MAChC,IAAI,QAAQ,aAAa,WAAW,KAAK,KAAK,SAAS;AAAA,IACxD;AAEA,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,UAAU,GAAG;AAChD,UAAI,MAAM,QAAW;AACpB,eAAO,CAAC,IAAI;AAAA,MACb;AAAA,IACD;AAEA,WAAO,WAAW,KAAK;AAEvB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAc;AACnB,WAAO,EAAE,OAAG,8BAAgB,MAAM,GAAG,IAAI,KAAK,SAAS,EAAE;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,SAAS,kBAAoC;AAC5C,WAAQ,KAAK,WAAW,OAAO,wBAAoB,uBAAS;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,IAAqB;AAC5B,QAAI,CAAC,KAAK,KAAK,EAAE,GAAG;AACnB,YAAM,IAAI,MAAM,OAAO,EAAE,iCAAiC,KAAK,QAAQ,GAAG;AAAA,IAC3E;AAEA,WAAO,GAAG,MAAM,KAAK,SAAS,SAAS,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,WAAW,QAAqC;AAC/C,WAAO,QAAQ,aAAa,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,KAAK,IAA4B;AAChC,QAAI,CAAC,GAAI,QAAO;AAChB,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC9C,UAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,EAAG,QAAO;AAAA,IACxC;AAEA,WAAO,GAAG,KAAK,SAAS,MAAM,MAAM;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,sBACC,yBACiE;AACjE,WAAO,IAAI,WAA+D,KAAK,UAAU;AAAA,MACxF;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,OAAO,KAAK;AAAA,MACZ,eAAe,KAAK;AAAA,IACrB,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,QAAiB,cAAqB;AAC9C,QAAI,gBAAgB,KAAK,UAAU,+BAA+B;AACjE,aAAO,KAAK,UAAU,8BAA8B,cAAc,MAAM;AAAA,IACzE;AACA,WAAO,KAAK,UAAU,SAAS,MAAM;AAAA,EACtC;AACD;AAcO,SAAS,iBACf,UACA,QAKkD;AAClD,SAAO,IAAI,WAAgD,UAAU;AAAA,IACpE,yBAAyB,OAAO,CAAC;AAAA,IACjC,WAAW,OAAO;AAAA,IAClB,OAAO,OAAO;AAAA,IACd,eAAe,OAAO;AAAA,EACvB,CAAC;AACF;AAeO,SAAS,aACf,IACA,MACwB;AACxB,MAAI,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,GAAG;AAC1B,UAAM,IAAI,MAAM,UAAU,KAAK,UAAU,EAAE,CAAC,mBAAmB,KAAK,QAAQ,KAAK;AAAA,EAClF;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -39,9 +39,9 @@ function reverseRecordsDiff(diff) {
|
|
|
39
39
|
function isRecordsDiffEmpty(diff) {
|
|
40
40
|
return Object.keys(diff.added).length === 0 && Object.keys(diff.updated).length === 0 && Object.keys(diff.removed).length === 0;
|
|
41
41
|
}
|
|
42
|
-
function squashRecordDiffs(diffs) {
|
|
43
|
-
const result = { added: {}, removed: {}, updated: {} };
|
|
44
|
-
squashRecordDiffsMutable(result, diffs);
|
|
42
|
+
function squashRecordDiffs(diffs, options) {
|
|
43
|
+
const result = options?.mutateFirstDiff ? diffs[0] : { added: {}, removed: {}, updated: {} };
|
|
44
|
+
squashRecordDiffsMutable(result, options?.mutateFirstDiff ? diffs.slice(1) : diffs);
|
|
45
45
|
return result;
|
|
46
46
|
}
|
|
47
47
|
function squashRecordDiffsMutable(target, diffs) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/RecordsDiff.ts"],
|
|
4
|
-
"sourcesContent": ["import { objectMapEntries } from '@tldraw/utils'\nimport { IdOf, UnknownRecord } from './BaseRecord'\n\n/**\n * A diff describing the changes to a record.\n *\n * @public\n */\nexport interface RecordsDiff<R extends UnknownRecord> {\n\tadded: Record<IdOf<R>, R>\n\tupdated: Record<IdOf<R>, [from: R, to: R]>\n\tremoved: Record<IdOf<R>, R>\n}\n\n/** @internal */\nexport function createEmptyRecordsDiff<R extends UnknownRecord>(): RecordsDiff<R> {\n\treturn { added: {}, updated: {}, removed: {} } as RecordsDiff<R>\n}\n\n/** @public */\nexport function reverseRecordsDiff(diff: RecordsDiff<any>) {\n\tconst result: RecordsDiff<any> = { added: diff.removed, removed: diff.added, updated: {} }\n\tfor (const [from, to] of Object.values(diff.updated)) {\n\t\tresult.updated[from.id] = [to, from]\n\t}\n\treturn result\n}\n\n/**\n * Is a records diff empty?\n * @internal\n */\nexport function isRecordsDiffEmpty<T extends UnknownRecord>(diff: RecordsDiff<T>) {\n\treturn (\n\t\tObject.keys(diff.added).length === 0 &&\n\t\tObject.keys(diff.updated).length === 0 &&\n\t\tObject.keys(diff.removed).length === 0\n\t)\n}\n\n/**\n * Squash a collection of diffs into a single diff.\n *\n * @param diffs - An array of diffs to squash.\n * @returns A single diff that represents the squashed diffs.\n * @public\n */\nexport function squashRecordDiffs<T extends UnknownRecord>(\n\tdiffs: RecordsDiff<T>[]\n): RecordsDiff<T> {\n\tconst result = { added: {}, removed: {}, updated: {} } as RecordsDiff<T
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiC;AAe1B,SAAS,yBAAkE;AACjF,SAAO,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AAC9C;AAGO,SAAS,mBAAmB,MAAwB;AAC1D,QAAM,SAA2B,EAAE,OAAO,KAAK,SAAS,SAAS,KAAK,OAAO,SAAS,CAAC,EAAE;AACzF,aAAW,CAAC,MAAM,EAAE,KAAK,OAAO,OAAO,KAAK,OAAO,GAAG;AACrD,WAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI;AAAA,EACpC;AACA,SAAO;AACR;AAMO,SAAS,mBAA4C,MAAsB;AACjF,SACC,OAAO,KAAK,KAAK,KAAK,EAAE,WAAW,KACnC,OAAO,KAAK,KAAK,OAAO,EAAE,WAAW,KACrC,OAAO,KAAK,KAAK,OAAO,EAAE,WAAW;AAEvC;
|
|
4
|
+
"sourcesContent": ["import { objectMapEntries } from '@tldraw/utils'\nimport { IdOf, UnknownRecord } from './BaseRecord'\n\n/**\n * A diff describing the changes to a record.\n *\n * @public\n */\nexport interface RecordsDiff<R extends UnknownRecord> {\n\tadded: Record<IdOf<R>, R>\n\tupdated: Record<IdOf<R>, [from: R, to: R]>\n\tremoved: Record<IdOf<R>, R>\n}\n\n/** @internal */\nexport function createEmptyRecordsDiff<R extends UnknownRecord>(): RecordsDiff<R> {\n\treturn { added: {}, updated: {}, removed: {} } as RecordsDiff<R>\n}\n\n/** @public */\nexport function reverseRecordsDiff(diff: RecordsDiff<any>) {\n\tconst result: RecordsDiff<any> = { added: diff.removed, removed: diff.added, updated: {} }\n\tfor (const [from, to] of Object.values(diff.updated)) {\n\t\tresult.updated[from.id] = [to, from]\n\t}\n\treturn result\n}\n\n/**\n * Is a records diff empty?\n * @internal\n */\nexport function isRecordsDiffEmpty<T extends UnknownRecord>(diff: RecordsDiff<T>) {\n\treturn (\n\t\tObject.keys(diff.added).length === 0 &&\n\t\tObject.keys(diff.updated).length === 0 &&\n\t\tObject.keys(diff.removed).length === 0\n\t)\n}\n\n/**\n * Squash a collection of diffs into a single diff.\n *\n * @param diffs - An array of diffs to squash.\n * @param options - An optional object with a `mutateFirstDiff` property. If `mutateFirstDiff` is true, the first diff in the array will be mutated in-place.\n * @returns A single diff that represents the squashed diffs.\n * @public\n */\nexport function squashRecordDiffs<T extends UnknownRecord>(\n\tdiffs: RecordsDiff<T>[],\n\toptions?: {\n\t\tmutateFirstDiff?: boolean\n\t}\n): RecordsDiff<T> {\n\tconst result = options?.mutateFirstDiff\n\t\t? diffs[0]\n\t\t: ({ added: {}, removed: {}, updated: {} } as RecordsDiff<T>)\n\n\tsquashRecordDiffsMutable(result, options?.mutateFirstDiff ? diffs.slice(1) : diffs)\n\treturn result\n}\n\n/**\n * Apply the array `diffs` to the `target` diff, mutating it in-place.\n * @internal\n */\nexport function squashRecordDiffsMutable<T extends UnknownRecord>(\n\ttarget: RecordsDiff<T>,\n\tdiffs: RecordsDiff<T>[]\n): void {\n\tfor (const diff of diffs) {\n\t\tfor (const [id, value] of objectMapEntries(diff.added)) {\n\t\t\tif (target.removed[id]) {\n\t\t\t\tconst original = target.removed[id]\n\t\t\t\tdelete target.removed[id]\n\t\t\t\tif (original !== value) {\n\t\t\t\t\ttarget.updated[id] = [original, value]\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttarget.added[id] = value\n\t\t\t}\n\t\t}\n\n\t\tfor (const [id, [_from, to]] of objectMapEntries(diff.updated)) {\n\t\t\tif (target.added[id]) {\n\t\t\t\ttarget.added[id] = to\n\t\t\t\tdelete target.updated[id]\n\t\t\t\tdelete target.removed[id]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (target.updated[id]) {\n\t\t\t\ttarget.updated[id] = [target.updated[id][0], to]\n\t\t\t\tdelete target.removed[id]\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\ttarget.updated[id] = diff.updated[id]\n\t\t\tdelete target.removed[id]\n\t\t}\n\n\t\tfor (const [id, value] of objectMapEntries(diff.removed)) {\n\t\t\t// the same record was added in this diff sequence, just drop it\n\t\t\tif (target.added[id]) {\n\t\t\t\tdelete target.added[id]\n\t\t\t} else if (target.updated[id]) {\n\t\t\t\ttarget.removed[id] = target.updated[id][0]\n\t\t\t\tdelete target.updated[id]\n\t\t\t} else {\n\t\t\t\ttarget.removed[id] = value\n\t\t\t}\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiC;AAe1B,SAAS,yBAAkE;AACjF,SAAO,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AAC9C;AAGO,SAAS,mBAAmB,MAAwB;AAC1D,QAAM,SAA2B,EAAE,OAAO,KAAK,SAAS,SAAS,KAAK,OAAO,SAAS,CAAC,EAAE;AACzF,aAAW,CAAC,MAAM,EAAE,KAAK,OAAO,OAAO,KAAK,OAAO,GAAG;AACrD,WAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI;AAAA,EACpC;AACA,SAAO;AACR;AAMO,SAAS,mBAA4C,MAAsB;AACjF,SACC,OAAO,KAAK,KAAK,KAAK,EAAE,WAAW,KACnC,OAAO,KAAK,KAAK,OAAO,EAAE,WAAW,KACrC,OAAO,KAAK,KAAK,OAAO,EAAE,WAAW;AAEvC;AAUO,SAAS,kBACf,OACA,SAGiB;AACjB,QAAM,SAAS,SAAS,kBACrB,MAAM,CAAC,IACN,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AAE1C,2BAAyB,QAAQ,SAAS,kBAAkB,MAAM,MAAM,CAAC,IAAI,KAAK;AAClF,SAAO;AACR;AAMO,SAAS,yBACf,QACA,OACO;AACP,aAAW,QAAQ,OAAO;AACzB,eAAW,CAAC,IAAI,KAAK,SAAK,+BAAiB,KAAK,KAAK,GAAG;AACvD,UAAI,OAAO,QAAQ,EAAE,GAAG;AACvB,cAAM,WAAW,OAAO,QAAQ,EAAE;AAClC,eAAO,OAAO,QAAQ,EAAE;AACxB,YAAI,aAAa,OAAO;AACvB,iBAAO,QAAQ,EAAE,IAAI,CAAC,UAAU,KAAK;AAAA,QACtC;AAAA,MACD,OAAO;AACN,eAAO,MAAM,EAAE,IAAI;AAAA,MACpB;AAAA,IACD;AAEA,eAAW,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,SAAK,+BAAiB,KAAK,OAAO,GAAG;AAC/D,UAAI,OAAO,MAAM,EAAE,GAAG;AACrB,eAAO,MAAM,EAAE,IAAI;AACnB,eAAO,OAAO,QAAQ,EAAE;AACxB,eAAO,OAAO,QAAQ,EAAE;AACxB;AAAA,MACD;AACA,UAAI,OAAO,QAAQ,EAAE,GAAG;AACvB,eAAO,QAAQ,EAAE,IAAI,CAAC,OAAO,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE;AAC/C,eAAO,OAAO,QAAQ,EAAE;AACxB;AAAA,MACD;AAEA,aAAO,QAAQ,EAAE,IAAI,KAAK,QAAQ,EAAE;AACpC,aAAO,OAAO,QAAQ,EAAE;AAAA,IACzB;AAEA,eAAW,CAAC,IAAI,KAAK,SAAK,+BAAiB,KAAK,OAAO,GAAG;AAEzD,UAAI,OAAO,MAAM,EAAE,GAAG;AACrB,eAAO,OAAO,MAAM,EAAE;AAAA,MACvB,WAAW,OAAO,QAAQ,EAAE,GAAG;AAC9B,eAAO,QAAQ,EAAE,IAAI,OAAO,QAAQ,EAAE,EAAE,CAAC;AACzC,eAAO,OAAO,QAAQ,EAAE;AAAA,MACzB,OAAO;AACN,eAAO,QAAQ,EAAE,IAAI;AAAA,MACtB;AAAA,IACD;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-cjs/lib/Store.js
CHANGED
|
@@ -328,20 +328,11 @@ class Store {
|
|
|
328
328
|
schema: this.schema.serialize()
|
|
329
329
|
};
|
|
330
330
|
}
|
|
331
|
-
/**
|
|
332
|
-
* @deprecated use `getSnapshot` from the 'tldraw' package instead.
|
|
333
|
-
*/
|
|
334
|
-
getSnapshot(scope = "document") {
|
|
335
|
-
console.warn(
|
|
336
|
-
"[tldraw] `Store.getSnapshot` is deprecated and will be removed in a future release. Use `getSnapshot` from the `tldraw` package instead."
|
|
337
|
-
);
|
|
338
|
-
return this.getStoreSnapshot(scope);
|
|
339
|
-
}
|
|
340
331
|
/**
|
|
341
332
|
* Migrate a serialized snapshot of the store and its schema.
|
|
342
333
|
*
|
|
343
334
|
* ```ts
|
|
344
|
-
* const snapshot = store.
|
|
335
|
+
* const snapshot = store.getStoreSnapshot()
|
|
345
336
|
* store.migrateSnapshot(snapshot)
|
|
346
337
|
* ```
|
|
347
338
|
*
|
|
@@ -386,16 +377,6 @@ class Store {
|
|
|
386
377
|
this.sideEffects.setIsEnabled(prevSideEffectsEnabled);
|
|
387
378
|
}
|
|
388
379
|
}
|
|
389
|
-
/**
|
|
390
|
-
* @public
|
|
391
|
-
* @deprecated use `loadSnapshot` from the 'tldraw' package instead.
|
|
392
|
-
*/
|
|
393
|
-
loadSnapshot(snapshot) {
|
|
394
|
-
console.warn(
|
|
395
|
-
"[tldraw] `Store.loadSnapshot` is deprecated and will be removed in a future release. Use `loadSnapshot` from the 'tldraw' package instead."
|
|
396
|
-
);
|
|
397
|
-
this.loadStoreSnapshot(snapshot);
|
|
398
|
-
}
|
|
399
380
|
/**
|
|
400
381
|
* Get an array of all values in the store.
|
|
401
382
|
*
|