@tldraw/store 3.16.0-next.282b7be564ae → 3.16.0-next.2f9d39693e4c
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 +11 -11
- package/dist-cjs/index.d.ts +2 -40
- 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/Store.js +1 -20
- package/dist-cjs/lib/Store.js.map +2 -2
- package/dist-cjs/lib/StoreSchema.js +1 -0
- package/dist-cjs/lib/StoreSchema.js.map +2 -2
- package/dist-cjs/lib/migrate.js +0 -27
- package/dist-cjs/lib/migrate.js.map +2 -2
- package/dist-esm/index.d.mts +2 -40
- 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/Store.mjs +1 -20
- package/dist-esm/lib/Store.mjs.map +2 -2
- package/dist-esm/lib/StoreSchema.mjs +1 -0
- package/dist-esm/lib/StoreSchema.mjs.map +2 -2
- package/dist-esm/lib/migrate.mjs +0 -27
- package/dist-esm/lib/migrate.mjs.map +2 -2
- package/package.json +10 -18
- package/src/index.ts +0 -1
- package/src/lib/RecordType.ts +0 -17
- package/src/lib/Store.ts +1 -22
- package/src/lib/StoreSchema.ts +1 -0
- package/src/lib/migrate.ts +0 -39
- package/src/lib/test/AtomMap.test.ts +2 -1
- package/src/lib/test/dependsOn.test.ts +2 -2
- package/src/lib/test/recordStore.test.ts +40 -37
- package/src/lib/test/sortMigrations.test.ts +4 -4
- package/src/lib/test/validateMigrations.test.ts +8 -8
- package/src/lib/test/defineMigrations.test.ts +0 -232
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ 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({
|
|
@@ -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
|
```
|
|
@@ -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
|
*
|
|
@@ -630,15 +604,11 @@ export declare class Store<R extends UnknownRecord = UnknownRecord, Props = unkn
|
|
|
630
604
|
* @public
|
|
631
605
|
*/
|
|
632
606
|
getStoreSnapshot(scope?: 'all' | RecordScope): StoreSnapshot<R>;
|
|
633
|
-
/**
|
|
634
|
-
* @deprecated use `getSnapshot` from the 'tldraw' package instead.
|
|
635
|
-
*/
|
|
636
|
-
getSnapshot(scope?: 'all' | RecordScope): StoreSnapshot<R>;
|
|
637
607
|
/**
|
|
638
608
|
* Migrate a serialized snapshot of the store and its schema.
|
|
639
609
|
*
|
|
640
610
|
* ```ts
|
|
641
|
-
* const snapshot = store.
|
|
611
|
+
* const snapshot = store.getStoreSnapshot()
|
|
642
612
|
* store.migrateSnapshot(snapshot)
|
|
643
613
|
* ```
|
|
644
614
|
*
|
|
@@ -658,11 +628,6 @@ export declare class Store<R extends UnknownRecord = UnknownRecord, Props = unkn
|
|
|
658
628
|
* @public
|
|
659
629
|
*/
|
|
660
630
|
loadStoreSnapshot(snapshot: StoreSnapshot<R>): void;
|
|
661
|
-
/**
|
|
662
|
-
* @public
|
|
663
|
-
* @deprecated use `loadSnapshot` from the 'tldraw' package instead.
|
|
664
|
-
*/
|
|
665
|
-
loadSnapshot(snapshot: StoreSnapshot<R>): void;
|
|
666
631
|
/**
|
|
667
632
|
* Get an array of all values in the store.
|
|
668
633
|
*
|
|
@@ -905,10 +870,7 @@ export declare class StoreSchema<R extends UnknownRecord, P = unknown> {
|
|
|
905
870
|
}): MigrationResult<SerializedStore<R>>;
|
|
906
871
|
/* Excluded from this release type: createIntegrityChecker */
|
|
907
872
|
serialize(): SerializedSchemaV2;
|
|
908
|
-
|
|
909
|
-
* @deprecated This is only here for legacy reasons, don't use it unless you have david's blessing!
|
|
910
|
-
*/
|
|
911
|
-
serializeEarliestVersion(): SerializedSchema;
|
|
873
|
+
/* Excluded from this release type: serializeEarliestVersion */
|
|
912
874
|
/* Excluded from this release type: getType */
|
|
913
875
|
}
|
|
914
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-next.
|
|
57
|
+
"3.16.0-next.2f9d39693e4c",
|
|
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": "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",
|
|
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
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/Store.ts"],
|
|
4
|
-
"sourcesContent": ["import { Atom, Reactor, Signal, atom, computed, reactor, transact } from '@tldraw/state'\nimport {\n\tWeakCache,\n\tassert,\n\tfilterEntries,\n\tgetOwnProperty,\n\tisEqual,\n\tobjectMapEntries,\n\tobjectMapKeys,\n\tobjectMapValues,\n\tthrottleToNextFrame,\n\tuniqueId,\n} from '@tldraw/utils'\nimport { AtomMap } from './AtomMap'\nimport { IdOf, RecordId, UnknownRecord } from './BaseRecord'\nimport { RecordScope } from './RecordType'\nimport { RecordsDiff, squashRecordDiffs } from './RecordsDiff'\nimport { StoreQueries } from './StoreQueries'\nimport { SerializedSchema, StoreSchema } from './StoreSchema'\nimport { StoreSideEffects } from './StoreSideEffects'\nimport { devFreeze } from './devFreeze'\n\n/** @public */\nexport type RecordFromId<K extends RecordId<UnknownRecord>> =\n\tK extends RecordId<infer R> ? R : never\n\n/**\n * A diff describing the changes to a collection.\n *\n * @public\n */\nexport interface CollectionDiff<T> {\n\tadded?: Set<T>\n\tremoved?: Set<T>\n}\n\n/** @public */\nexport type ChangeSource = 'user' | 'remote'\n\n/** @public */\nexport interface StoreListenerFilters {\n\tsource: ChangeSource | 'all'\n\tscope: RecordScope | 'all'\n}\n\n/**\n * An entry containing changes that originated either by user actions or remote changes.\n *\n * @public\n */\nexport interface HistoryEntry<R extends UnknownRecord = UnknownRecord> {\n\tchanges: RecordsDiff<R>\n\tsource: ChangeSource\n}\n\n/**\n * A function that will be called when the history changes.\n *\n * @public\n */\nexport type StoreListener<R extends UnknownRecord> = (entry: HistoryEntry<R>) => void\n\n/**\n * A record store is a collection of records of different types.\n *\n * @public\n */\nexport interface ComputedCache<Data, R extends UnknownRecord> {\n\tget(id: IdOf<R>): Data | undefined\n}\n\n/** @public */\nexport interface CreateComputedCacheOpts<Data, R extends UnknownRecord> {\n\tareRecordsEqual?(a: R, b: R): boolean\n\tareResultsEqual?(a: Data, b: Data): boolean\n}\n\n/**\n * A serialized snapshot of the record store's values.\n *\n * @public\n */\nexport type SerializedStore<R extends UnknownRecord> = Record<IdOf<R>, R>\n\n/** @public */\nexport interface StoreSnapshot<R extends UnknownRecord> {\n\tstore: SerializedStore<R>\n\tschema: SerializedSchema\n}\n\n/** @public */\nexport interface StoreValidator<R extends UnknownRecord> {\n\tvalidate(record: unknown): R\n\tvalidateUsingKnownGoodVersion?(knownGoodVersion: R, record: unknown): R\n}\n\n/** @public */\nexport type StoreValidators<R extends UnknownRecord> = {\n\t[K in R['typeName']]: StoreValidator<Extract<R, { typeName: K }>>\n}\n\n/** @public */\nexport interface StoreError {\n\terror: Error\n\tphase: 'initialize' | 'createRecord' | 'updateRecord' | 'tests'\n\trecordBefore?: unknown\n\trecordAfter: unknown\n\tisExistingValidationIssue: boolean\n}\n\n/** @internal */\nexport type StoreRecord<S extends Store<any>> = S extends Store<infer R> ? R : never\n\n/**\n * A store of records.\n *\n * @public\n */\nexport class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {\n\t/**\n\t * The random id of the store.\n\t */\n\tpublic readonly id: string\n\t/**\n\t * An AtomMap containing the stores records.\n\t *\n\t * @internal\n\t * @readonly\n\t */\n\tprivate readonly records: AtomMap<IdOf<R>, R>\n\n\t/**\n\t * An atom containing the store's history.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\treadonly history: Atom<number, RecordsDiff<R>> = atom('history', 0, {\n\t\thistoryLength: 1000,\n\t})\n\n\t/**\n\t * A StoreQueries instance for this store.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\treadonly query: StoreQueries<R>\n\n\t/**\n\t * A set containing listeners that have been added to this store.\n\t *\n\t * @internal\n\t */\n\tprivate listeners = new Set<{ onHistory: StoreListener<R>; filters: StoreListenerFilters }>()\n\n\t/**\n\t * An array of history entries that have not yet been flushed.\n\t *\n\t * @internal\n\t */\n\tprivate historyAccumulator = new HistoryAccumulator<R>()\n\n\t/**\n\t * A reactor that responds to changes to the history by squashing the accumulated history and\n\t * notifying listeners of the changes.\n\t *\n\t * @internal\n\t */\n\tprivate historyReactor: Reactor\n\n\t/**\n\t * Function to dispose of any in-flight timeouts.\n\t *\n\t * @internal\n\t */\n\tprivate cancelHistoryReactor(): void {\n\t\t/* noop */\n\t}\n\n\treadonly schema: StoreSchema<R, Props>\n\n\treadonly props: Props\n\n\tpublic readonly scopedTypes: { readonly [K in RecordScope]: ReadonlySet<R['typeName']> }\n\n\tpublic readonly sideEffects = new StoreSideEffects<R>(this)\n\n\tconstructor(config: {\n\t\tid?: string\n\t\t/** The store's initial data. */\n\t\tinitialData?: SerializedStore<R>\n\t\t/**\n\t\t * A map of validators for each record type. A record's validator will be called when the record\n\t\t * is created or updated. It should throw an error if the record is invalid.\n\t\t */\n\t\tschema: StoreSchema<R, Props>\n\t\tprops: Props\n\t}) {\n\t\tconst { initialData, schema, id } = config\n\n\t\tthis.id = id ?? uniqueId()\n\t\tthis.schema = schema\n\t\tthis.props = config.props\n\n\t\tif (initialData) {\n\t\t\tthis.records = new AtomMap(\n\t\t\t\t'store',\n\t\t\t\tobjectMapEntries(initialData).map(([id, record]) => [\n\t\t\t\t\tid,\n\t\t\t\t\tdevFreeze(this.schema.validateRecord(this, record, 'initialize', null)),\n\t\t\t\t])\n\t\t\t)\n\t\t} else {\n\t\t\tthis.records = new AtomMap('store')\n\t\t}\n\n\t\tthis.query = new StoreQueries<R>(this.records, this.history)\n\n\t\tthis.historyReactor = reactor(\n\t\t\t'Store.historyReactor',\n\t\t\t() => {\n\t\t\t\t// deref to make sure we're subscribed regardless of whether we need to propagate\n\t\t\t\tthis.history.get()\n\t\t\t\t// If we have accumulated history, flush it and update listeners\n\t\t\t\tthis._flushHistory()\n\t\t\t},\n\t\t\t{ scheduleEffect: (cb) => (this.cancelHistoryReactor = throttleToNextFrame(cb)) }\n\t\t)\n\t\tthis.scopedTypes = {\n\t\t\tdocument: new Set(\n\t\t\t\tobjectMapValues(this.schema.types)\n\t\t\t\t\t.filter((t) => t.scope === 'document')\n\t\t\t\t\t.map((t) => t.typeName)\n\t\t\t),\n\t\t\tsession: new Set(\n\t\t\t\tobjectMapValues(this.schema.types)\n\t\t\t\t\t.filter((t) => t.scope === 'session')\n\t\t\t\t\t.map((t) => t.typeName)\n\t\t\t),\n\t\t\tpresence: new Set(\n\t\t\t\tobjectMapValues(this.schema.types)\n\t\t\t\t\t.filter((t) => t.scope === 'presence')\n\t\t\t\t\t.map((t) => t.typeName)\n\t\t\t),\n\t\t}\n\t}\n\n\tpublic _flushHistory() {\n\t\t// If we have accumulated history, flush it and update listeners\n\t\tif (this.historyAccumulator.hasChanges()) {\n\t\t\tconst entries = this.historyAccumulator.flush()\n\t\t\tfor (const { changes, source } of entries) {\n\t\t\t\tlet instanceChanges = null as null | RecordsDiff<R>\n\t\t\t\tlet documentChanges = null as null | RecordsDiff<R>\n\t\t\t\tlet presenceChanges = null as null | RecordsDiff<R>\n\t\t\t\tfor (const { onHistory, filters } of this.listeners) {\n\t\t\t\t\tif (filters.source !== 'all' && filters.source !== source) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (filters.scope !== 'all') {\n\t\t\t\t\t\tif (filters.scope === 'document') {\n\t\t\t\t\t\t\tdocumentChanges ??= this.filterChangesByScope(changes, 'document')\n\t\t\t\t\t\t\tif (!documentChanges) continue\n\t\t\t\t\t\t\tonHistory({ changes: documentChanges, source })\n\t\t\t\t\t\t} else if (filters.scope === 'session') {\n\t\t\t\t\t\t\tinstanceChanges ??= this.filterChangesByScope(changes, 'session')\n\t\t\t\t\t\t\tif (!instanceChanges) continue\n\t\t\t\t\t\t\tonHistory({ changes: instanceChanges, source })\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpresenceChanges ??= this.filterChangesByScope(changes, 'presence')\n\t\t\t\t\t\t\tif (!presenceChanges) continue\n\t\t\t\t\t\t\tonHistory({ changes: presenceChanges, source })\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonHistory({ changes, source })\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdispose() {\n\t\tthis.cancelHistoryReactor()\n\t}\n\n\t/**\n\t * Filters out non-document changes from a diff. Returns null if there are no changes left.\n\t * @param change - the records diff\n\t * @param scope - the records scope\n\t * @returns\n\t */\n\tfilterChangesByScope(change: RecordsDiff<R>, scope: RecordScope) {\n\t\tconst result = {\n\t\t\tadded: filterEntries(change.added, (_, r) => this.scopedTypes[scope].has(r.typeName)),\n\t\t\tupdated: filterEntries(change.updated, (_, r) => this.scopedTypes[scope].has(r[1].typeName)),\n\t\t\tremoved: filterEntries(change.removed, (_, r) => this.scopedTypes[scope].has(r.typeName)),\n\t\t}\n\t\tif (\n\t\t\tObject.keys(result.added).length === 0 &&\n\t\t\tObject.keys(result.updated).length === 0 &&\n\t\t\tObject.keys(result.removed).length === 0\n\t\t) {\n\t\t\treturn null\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Update the history with a diff of changes.\n\t *\n\t * @param changes - The changes to add to the history.\n\t */\n\tprivate updateHistory(changes: RecordsDiff<R>): void {\n\t\tthis.historyAccumulator.add({\n\t\t\tchanges,\n\t\t\tsource: this.isMergingRemoteChanges ? 'remote' : 'user',\n\t\t})\n\t\tif (this.listeners.size === 0) {\n\t\t\tthis.historyAccumulator.clear()\n\t\t}\n\t\tthis.history.set(this.history.get() + 1, changes)\n\t}\n\n\tvalidate(phase: 'initialize' | 'createRecord' | 'updateRecord' | 'tests') {\n\t\tthis.allRecords().forEach((record) => this.schema.validateRecord(this, record, phase, null))\n\t}\n\n\t/**\n\t * Add some records to the store. It's an error if they already exist.\n\t *\n\t * @param records - The records to add.\n\t * @param phaseOverride - The phase override.\n\t * @public\n\t */\n\tput(records: R[], phaseOverride?: 'initialize'): void {\n\t\tthis.atomic(() => {\n\t\t\tconst updates: Record<IdOf<UnknownRecord>, [from: R, to: R]> = {}\n\t\t\tconst additions: Record<IdOf<UnknownRecord>, R> = {}\n\n\t\t\t// Iterate through all records, creating, updating or removing as needed\n\t\t\tlet record: R\n\n\t\t\t// There's a chance that, despite having records, all of the values are\n\t\t\t// identical to what they were before; and so we'd end up with an \"empty\"\n\t\t\t// history entry. Let's keep track of whether we've actually made any\n\t\t\t// changes (e.g. additions, deletions, or updates that produce a new value).\n\t\t\tlet didChange = false\n\n\t\t\tconst source = this.isMergingRemoteChanges ? 'remote' : 'user'\n\n\t\t\tfor (let i = 0, n = records.length; i < n; i++) {\n\t\t\t\trecord = records[i]\n\n\t\t\t\tconst initialValue = this.records.__unsafe__getWithoutCapture(record.id)\n\t\t\t\t// If we already have an atom for this record, update its value.\n\t\t\t\tif (initialValue) {\n\t\t\t\t\t// If we have a beforeUpdate callback, run it against the initial and next records\n\t\t\t\t\trecord = this.sideEffects.handleBeforeChange(initialValue, record, source)\n\n\t\t\t\t\t// Validate the record\n\t\t\t\t\tconst validated = this.schema.validateRecord(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\trecord,\n\t\t\t\t\t\tphaseOverride ?? 'updateRecord',\n\t\t\t\t\t\tinitialValue\n\t\t\t\t\t)\n\n\t\t\t\t\tif (validated === initialValue) continue\n\n\t\t\t\t\trecord = devFreeze(record)\n\t\t\t\t\tthis.records.set(record.id, record)\n\n\t\t\t\t\tdidChange = true\n\t\t\t\t\tupdates[record.id] = [initialValue, record]\n\t\t\t\t\tthis.addDiffForAfterEvent(initialValue, record)\n\t\t\t\t} else {\n\t\t\t\t\trecord = this.sideEffects.handleBeforeCreate(record, source)\n\n\t\t\t\t\tdidChange = true\n\n\t\t\t\t\t// If we don't have an atom, create one.\n\n\t\t\t\t\t// Validate the record\n\t\t\t\t\trecord = this.schema.validateRecord(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\trecord as R,\n\t\t\t\t\t\tphaseOverride ?? 'createRecord',\n\t\t\t\t\t\tnull\n\t\t\t\t\t)\n\n\t\t\t\t\t// freeze it\n\t\t\t\t\trecord = devFreeze(record)\n\n\t\t\t\t\t// Mark the change as a new addition.\n\t\t\t\t\tadditions[record.id] = record\n\t\t\t\t\tthis.addDiffForAfterEvent(null, record)\n\n\t\t\t\t\tthis.records.set(record.id, record)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we did change, update the history\n\t\t\tif (!didChange) return\n\t\t\tthis.updateHistory({\n\t\t\t\tadded: additions,\n\t\t\t\tupdated: updates,\n\t\t\t\tremoved: {} as Record<IdOf<R>, R>,\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Remove some records from the store via their ids.\n\t *\n\t * @param ids - The ids of the records to remove.\n\t * @public\n\t */\n\tremove(ids: IdOf<R>[]): void {\n\t\tthis.atomic(() => {\n\t\t\tconst toDelete = new Set<IdOf<R>>(ids)\n\t\t\tconst source = this.isMergingRemoteChanges ? 'remote' : 'user'\n\n\t\t\tif (this.sideEffects.isEnabled()) {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst record = this.records.__unsafe__getWithoutCapture(id)\n\t\t\t\t\tif (!record) continue\n\n\t\t\t\t\tif (this.sideEffects.handleBeforeDelete(record, source) === false) {\n\t\t\t\t\t\ttoDelete.delete(id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst actuallyDeleted = this.records.deleteMany(toDelete)\n\t\t\tif (actuallyDeleted.length === 0) return\n\n\t\t\tconst removed = {} as RecordsDiff<R>['removed']\n\t\t\tfor (const [id, record] of actuallyDeleted) {\n\t\t\t\tremoved[id] = record\n\t\t\t\tthis.addDiffForAfterEvent(record, null)\n\t\t\t}\n\n\t\t\t// Update the history with the removed records.\n\t\t\tthis.updateHistory({ added: {}, updated: {}, removed } as RecordsDiff<R>)\n\t\t})\n\t}\n\n\t/**\n\t * Get the value of a store record by its id.\n\t *\n\t * @param id - The id of the record to get.\n\t * @public\n\t */\n\tget<K extends IdOf<R>>(id: K): RecordFromId<K> | undefined {\n\t\treturn this.records.get(id) as RecordFromId<K> | undefined\n\t}\n\n\t/**\n\t * Get the value of a store record by its id without updating its epoch.\n\t *\n\t * @param id - The id of the record to get.\n\t * @public\n\t */\n\tunsafeGetWithoutCapture<K extends IdOf<R>>(id: K): RecordFromId<K> | undefined {\n\t\treturn this.records.__unsafe__getWithoutCapture(id) as RecordFromId<K> | undefined\n\t}\n\n\t/**\n\t * Creates a JSON payload from the record store.\n\t *\n\t * @param scope - The scope of records to serialize. Defaults to 'document'.\n\t * @returns The record store snapshot as a JSON payload.\n\t */\n\tserialize(scope: RecordScope | 'all' = 'document'): SerializedStore<R> {\n\t\tconst result = {} as SerializedStore<R>\n\t\tfor (const [id, record] of this.records) {\n\t\t\tif (scope === 'all' || this.scopedTypes[scope].has(record.typeName)) {\n\t\t\t\tresult[id as IdOf<R>] = record\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Get a serialized snapshot of the store and its schema.\n\t *\n\t * ```ts\n\t * const snapshot = store.getStoreSnapshot()\n\t * store.loadStoreSnapshot(snapshot)\n\t * ```\n\t *\n\t * @param scope - The scope of records to serialize. Defaults to 'document'.\n\t *\n\t * @public\n\t */\n\tgetStoreSnapshot(scope: RecordScope | 'all' = 'document'): StoreSnapshot<R> {\n\t\treturn {\n\t\t\tstore: this.serialize(scope),\n\t\t\tschema: this.schema.serialize(),\n\t\t}\n\t}\n\n\t/**\n\t * @deprecated use `getSnapshot` from the 'tldraw' package instead.\n\t */\n\tgetSnapshot(scope: RecordScope | 'all' = 'document') {\n\t\tconsole.warn(\n\t\t\t'[tldraw] `Store.getSnapshot` is deprecated and will be removed in a future release. Use `getSnapshot` from the `tldraw` package instead.'\n\t\t)\n\t\treturn this.getStoreSnapshot(scope)\n\t}\n\n\t/**\n\t * Migrate a serialized snapshot of the store and its schema.\n\t *\n\t * ```ts\n\t * const snapshot = store.getSnapshot()\n\t * store.migrateSnapshot(snapshot)\n\t * ```\n\t *\n\t * @param snapshot - The snapshot to load.\n\t * @public\n\t */\n\tmigrateSnapshot(snapshot: StoreSnapshot<R>): StoreSnapshot<R> {\n\t\tconst migrationResult = this.schema.migrateStoreSnapshot(snapshot)\n\n\t\tif (migrationResult.type === 'error') {\n\t\t\tthrow new Error(`Failed to migrate snapshot: ${migrationResult.reason}`)\n\t\t}\n\n\t\treturn {\n\t\t\tstore: migrationResult.value,\n\t\t\tschema: this.schema.serialize(),\n\t\t}\n\t}\n\n\t/**\n\t * Load a serialized snapshot.\n\t *\n\t * ```ts\n\t * const snapshot = store.getStoreSnapshot()\n\t * store.loadStoreSnapshot(snapshot)\n\t * ```\n\t *\n\t * @param snapshot - The snapshot to load.\n\t * @public\n\t */\n\tloadStoreSnapshot(snapshot: StoreSnapshot<R>): void {\n\t\tconst migrationResult = this.schema.migrateStoreSnapshot(snapshot)\n\n\t\tif (migrationResult.type === 'error') {\n\t\t\tthrow new Error(`Failed to migrate snapshot: ${migrationResult.reason}`)\n\t\t}\n\n\t\tconst prevSideEffectsEnabled = this.sideEffects.isEnabled()\n\t\ttry {\n\t\t\tthis.sideEffects.setIsEnabled(false)\n\t\t\tthis.atomic(() => {\n\t\t\t\tthis.clear()\n\t\t\t\tthis.put(Object.values(migrationResult.value))\n\t\t\t\tthis.ensureStoreIsUsable()\n\t\t\t})\n\t\t} finally {\n\t\t\tthis.sideEffects.setIsEnabled(prevSideEffectsEnabled)\n\t\t}\n\t}\n\n\t/**\n\t * @public\n\t * @deprecated use `loadSnapshot` from the 'tldraw' package instead.\n\t */\n\tloadSnapshot(snapshot: StoreSnapshot<R>) {\n\t\tconsole.warn(\n\t\t\t\"[tldraw] `Store.loadSnapshot` is deprecated and will be removed in a future release. Use `loadSnapshot` from the 'tldraw' package instead.\"\n\t\t)\n\t\tthis.loadStoreSnapshot(snapshot)\n\t}\n\n\t/**\n\t * Get an array of all values in the store.\n\t *\n\t * @returns An array of all values in the store.\n\t * @public\n\t */\n\tallRecords(): R[] {\n\t\treturn Array.from(this.records.values())\n\t}\n\n\t/**\n\t * Removes all records from the store.\n\t *\n\t * @public\n\t */\n\tclear(): void {\n\t\tthis.remove(Array.from(this.records.keys()))\n\t}\n\n\t/**\n\t * Update a record. To update multiple records at once, use the `update` method of the\n\t * `TypedStore` class.\n\t *\n\t * @param id - The id of the record to update.\n\t * @param updater - A function that updates the record.\n\t */\n\tupdate<K extends IdOf<R>>(id: K, updater: (record: RecordFromId<K>) => RecordFromId<K>) {\n\t\tconst existing = this.unsafeGetWithoutCapture(id)\n\t\tif (!existing) {\n\t\t\tconsole.error(`Record ${id} not found. This is probably an error`)\n\t\t\treturn\n\t\t}\n\n\t\tthis.put([updater(existing) as any])\n\t}\n\n\t/**\n\t * Get whether the record store has a id.\n\t *\n\t * @param id - The id of the record to check.\n\t * @public\n\t */\n\thas<K extends IdOf<R>>(id: K): boolean {\n\t\treturn this.records.has(id)\n\t}\n\n\t/**\n\t * Add a new listener to the store.\n\t *\n\t * @param onHistory - The listener to call when the store updates.\n\t * @param filters - Filters to apply to the listener.\n\t * @returns A function to remove the listener.\n\t */\n\tlisten(onHistory: StoreListener<R>, filters?: Partial<StoreListenerFilters>) {\n\t\t// flush history so that this listener's history starts from exactly now\n\t\tthis._flushHistory()\n\n\t\tconst listener = {\n\t\t\tonHistory,\n\t\t\tfilters: {\n\t\t\t\tsource: filters?.source ?? 'all',\n\t\t\t\tscope: filters?.scope ?? 'all',\n\t\t\t},\n\t\t}\n\n\t\tif (!this.historyReactor.scheduler.isActivelyListening) {\n\t\t\tthis.historyReactor.start()\n\t\t\tthis.historyReactor.scheduler.execute()\n\t\t}\n\n\t\tthis.listeners.add(listener)\n\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener)\n\n\t\t\tif (this.listeners.size === 0) {\n\t\t\t\tthis.historyReactor.stop()\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isMergingRemoteChanges = false\n\n\t/**\n\t * Merge changes from a remote source\n\t *\n\t * @param fn - A function that merges the external changes.\n\t * @public\n\t */\n\tmergeRemoteChanges(fn: () => void) {\n\t\tif (this.isMergingRemoteChanges) {\n\t\t\treturn fn()\n\t\t}\n\n\t\tif (this._isInAtomicOp) {\n\t\t\tthrow new Error('Cannot merge remote changes while in atomic operation')\n\t\t}\n\n\t\ttry {\n\t\t\tthis.atomic(fn, true, true)\n\t\t} finally {\n\t\t\tthis.ensureStoreIsUsable()\n\t\t}\n\t}\n\n\t/**\n\t * Run `fn` and return a {@link RecordsDiff} of the changes that occurred as a result.\n\t */\n\textractingChanges(fn: () => void): RecordsDiff<R> {\n\t\tconst changes: Array<RecordsDiff<R>> = []\n\t\tconst dispose = this.historyAccumulator.addInterceptor((entry) => changes.push(entry.changes))\n\t\ttry {\n\t\t\ttransact(fn)\n\t\t\treturn squashRecordDiffs(changes)\n\t\t} finally {\n\t\t\tdispose()\n\t\t}\n\t}\n\n\tapplyDiff(\n\t\tdiff: RecordsDiff<R>,\n\t\t{\n\t\t\trunCallbacks = true,\n\t\t\tignoreEphemeralKeys = false,\n\t\t}: { runCallbacks?: boolean; ignoreEphemeralKeys?: boolean } = {}\n\t) {\n\t\tthis.atomic(() => {\n\t\t\tconst toPut = objectMapValues(diff.added)\n\n\t\t\tfor (const [_from, to] of objectMapValues(diff.updated)) {\n\t\t\t\tconst type = this.schema.getType(to.typeName)\n\t\t\t\tif (ignoreEphemeralKeys && type.ephemeralKeySet.size) {\n\t\t\t\t\tconst existing = this.get(to.id)\n\t\t\t\t\tif (!existing) {\n\t\t\t\t\t\ttoPut.push(to)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tlet changed: R | null = null\n\t\t\t\t\tfor (const [key, value] of Object.entries(to)) {\n\t\t\t\t\t\tif (type.ephemeralKeySet.has(key) || Object.is(value, getOwnProperty(existing, key))) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!changed) changed = { ...existing } as R\n\t\t\t\t\t\t;(changed as any)[key] = value\n\t\t\t\t\t}\n\t\t\t\t\tif (changed) toPut.push(changed)\n\t\t\t\t} else {\n\t\t\t\t\ttoPut.push(to)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst toRemove = objectMapKeys(diff.removed)\n\t\t\tif (toPut.length) {\n\t\t\t\tthis.put(toPut)\n\t\t\t}\n\t\t\tif (toRemove.length) {\n\t\t\t\tthis.remove(toRemove)\n\t\t\t}\n\t\t}, runCallbacks)\n\t}\n\n\t/**\n\t * Create a cache based on values in the store. Pass in a function that takes and ID and a\n\t * signal for the underlying record. Return a signal (usually a computed) for the cached value.\n\t * For simple derivations, use {@link Store.createComputedCache}. This function is useful if you\n\t * need more precise control over intermediate values.\n\t */\n\tcreateCache<Result, Record extends R = R>(\n\t\tcreate: (id: IdOf<Record>, recordSignal: Signal<R>) => Signal<Result>\n\t) {\n\t\tconst cache = new WeakCache<Atom<any>, Signal<Result>>()\n\t\treturn {\n\t\t\tget: (id: IdOf<Record>) => {\n\t\t\t\tconst atom = this.records.getAtom(id)\n\t\t\t\tif (!atom) return undefined\n\t\t\t\treturn cache.get(atom, () => create(id, atom as Signal<R>)).get()\n\t\t\t},\n\t\t}\n\t}\n\n\t/**\n\t * Create a computed cache.\n\t *\n\t * @param name - The name of the derivation cache.\n\t * @param derive - A function used to derive the value of the cache.\n\t * @param opts - Options for the computed cache.\n\t * @public\n\t */\n\tcreateComputedCache<Result, Record extends R = R>(\n\t\tname: string,\n\t\tderive: (record: Record) => Result | undefined,\n\t\topts?: CreateComputedCacheOpts<Result, Record>\n\t): ComputedCache<Result, Record> {\n\t\treturn this.createCache((id, record) => {\n\t\t\tconst recordSignal = opts?.areRecordsEqual\n\t\t\t\t? computed(`${name}:${id}:isEqual`, () => record.get(), { isEqual: opts.areRecordsEqual })\n\t\t\t\t: record\n\n\t\t\treturn computed<Result | undefined>(\n\t\t\t\tname + ':' + id,\n\t\t\t\t() => {\n\t\t\t\t\treturn derive(recordSignal.get() as Record)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tisEqual: opts?.areResultsEqual,\n\t\t\t\t}\n\t\t\t)\n\t\t})\n\t}\n\n\tprivate _integrityChecker?: () => void | undefined\n\n\t/** @internal */\n\tensureStoreIsUsable() {\n\t\tthis.atomic(() => {\n\t\t\tthis._integrityChecker ??= this.schema.createIntegrityChecker(this)\n\t\t\tthis._integrityChecker?.()\n\t\t})\n\t}\n\n\tprivate _isPossiblyCorrupted = false\n\t/** @internal */\n\tmarkAsPossiblyCorrupted() {\n\t\tthis._isPossiblyCorrupted = true\n\t}\n\t/** @internal */\n\tisPossiblyCorrupted() {\n\t\treturn this._isPossiblyCorrupted\n\t}\n\n\tprivate pendingAfterEvents: Map<IdOf<R>, { before: R | null; after: R | null }> | null = null\n\tprivate addDiffForAfterEvent(before: R | null, after: R | null) {\n\t\tassert(this.pendingAfterEvents, 'must be in event operation')\n\t\tif (before === after) return\n\t\tif (before && after) assert(before.id === after.id)\n\t\tif (!before && !after) return\n\t\tconst id = (before || after)!.id\n\t\tconst existing = this.pendingAfterEvents.get(id)\n\t\tif (existing) {\n\t\t\texisting.after = after\n\t\t} else {\n\t\t\tthis.pendingAfterEvents.set(id, { before, after })\n\t\t}\n\t}\n\tprivate flushAtomicCallbacks(isMergingRemoteChanges: boolean) {\n\t\tlet updateDepth = 0\n\t\tlet source: ChangeSource = isMergingRemoteChanges ? 'remote' : 'user'\n\t\twhile (this.pendingAfterEvents) {\n\t\t\tconst events = this.pendingAfterEvents\n\t\t\tthis.pendingAfterEvents = null\n\n\t\t\tif (!this.sideEffects.isEnabled()) continue\n\n\t\t\tupdateDepth++\n\t\t\tif (updateDepth > 100) {\n\t\t\t\tthrow new Error('Maximum store update depth exceeded, bailing out')\n\t\t\t}\n\n\t\t\tfor (const { before, after } of events.values()) {\n\t\t\t\tif (before && after && before !== after && !isEqual(before, after)) {\n\t\t\t\t\tthis.sideEffects.handleAfterChange(before, after, source)\n\t\t\t\t} else if (before && !after) {\n\t\t\t\t\tthis.sideEffects.handleAfterDelete(before, source)\n\t\t\t\t} else if (!before && after) {\n\t\t\t\t\tthis.sideEffects.handleAfterCreate(after, source)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!this.pendingAfterEvents) {\n\t\t\t\tthis.sideEffects.handleOperationComplete(source)\n\t\t\t} else {\n\t\t\t\t// if the side effects triggered by a remote operation resulted in more effects,\n\t\t\t\t// those extra effects should not be marked as originating remotely.\n\t\t\t\tsource = 'user'\n\t\t\t}\n\t\t}\n\t}\n\tprivate _isInAtomicOp = false\n\t/** @internal */\n\tatomic<T>(fn: () => T, runCallbacks = true, isMergingRemoteChanges = false): T {\n\t\treturn transact(() => {\n\t\t\tif (this._isInAtomicOp) {\n\t\t\t\tif (!this.pendingAfterEvents) this.pendingAfterEvents = new Map()\n\t\t\t\tconst prevSideEffectsEnabled = this.sideEffects.isEnabled()\n\t\t\t\tassert(!isMergingRemoteChanges, 'cannot call mergeRemoteChanges while in atomic operation')\n\t\t\t\ttry {\n\t\t\t\t\t// if we are in an atomic context with side effects ON allow switching before* callbacks OFF.\n\t\t\t\t\t// but don't allow switching them ON if they had been marked OFF before.\n\t\t\t\t\tif (prevSideEffectsEnabled && !runCallbacks) {\n\t\t\t\t\t\tthis.sideEffects.setIsEnabled(false)\n\t\t\t\t\t}\n\t\t\t\t\treturn fn()\n\t\t\t\t} finally {\n\t\t\t\t\tthis.sideEffects.setIsEnabled(prevSideEffectsEnabled)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.pendingAfterEvents = new Map()\n\t\t\tconst prevSideEffectsEnabled = this.sideEffects.isEnabled()\n\t\t\tthis.sideEffects.setIsEnabled(runCallbacks ?? prevSideEffectsEnabled)\n\t\t\tthis._isInAtomicOp = true\n\n\t\t\tif (isMergingRemoteChanges) {\n\t\t\t\tthis.isMergingRemoteChanges = true\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = fn()\n\t\t\t\tthis.isMergingRemoteChanges = false\n\n\t\t\t\tthis.flushAtomicCallbacks(isMergingRemoteChanges)\n\n\t\t\t\treturn result\n\t\t\t} finally {\n\t\t\t\tthis.pendingAfterEvents = null\n\t\t\t\tthis.sideEffects.setIsEnabled(prevSideEffectsEnabled)\n\t\t\t\tthis._isInAtomicOp = false\n\t\t\t\tthis.isMergingRemoteChanges = false\n\t\t\t}\n\t\t})\n\t}\n\n\t/** @internal */\n\taddHistoryInterceptor(fn: (entry: HistoryEntry<R>, source: ChangeSource) => void) {\n\t\treturn this.historyAccumulator.addInterceptor((entry) =>\n\t\t\tfn(entry, this.isMergingRemoteChanges ? 'remote' : 'user')\n\t\t)\n\t}\n}\n\n/**\n * Collect all history entries by their adjacent sources.\n * For example, [user, user, remote, remote, user] would result in [user, remote, user],\n * with adjacent entries of the same source squashed into a single entry.\n *\n * @param entries - The array of history entries.\n * @returns A map of history entries by their sources.\n * @public\n */\nfunction squashHistoryEntries<T extends UnknownRecord>(\n\tentries: HistoryEntry<T>[]\n): HistoryEntry<T>[] {\n\tif (entries.length === 0) return []\n\n\tconst chunked: HistoryEntry<T>[][] = []\n\tlet chunk: HistoryEntry<T>[] = [entries[0]]\n\tlet entry: HistoryEntry<T>\n\n\tfor (let i = 1, n = entries.length; i < n; i++) {\n\t\tentry = entries[i]\n\t\tif (chunk[0].source !== entry.source) {\n\t\t\tchunked.push(chunk)\n\t\t\tchunk = []\n\t\t}\n\t\tchunk.push(entry)\n\t}\n\t// Push the last chunk\n\tchunked.push(chunk)\n\n\treturn devFreeze(\n\t\tchunked.map((chunk) => ({\n\t\t\tsource: chunk[0].source,\n\t\t\tchanges: squashRecordDiffs(chunk.map((e) => e.changes)),\n\t\t}))\n\t)\n}\n\nclass HistoryAccumulator<T extends UnknownRecord> {\n\tprivate _history: HistoryEntry<T>[] = []\n\n\tprivate _interceptors: Set<(entry: HistoryEntry<T>) => void> = new Set()\n\n\taddInterceptor(fn: (entry: HistoryEntry<T>) => void) {\n\t\tthis._interceptors.add(fn)\n\t\treturn () => {\n\t\t\tthis._interceptors.delete(fn)\n\t\t}\n\t}\n\n\tadd(entry: HistoryEntry<T>) {\n\t\tthis._history.push(entry)\n\t\tfor (const interceptor of this._interceptors) {\n\t\t\tinterceptor(entry)\n\t\t}\n\t}\n\n\tflush() {\n\t\tconst history = squashHistoryEntries(this._history)\n\t\tthis._history = []\n\t\treturn history\n\t}\n\n\tclear() {\n\t\tthis._history = []\n\t}\n\n\thasChanges() {\n\t\treturn this._history.length > 0\n\t}\n}\n\n/** @public */\nexport type StoreObject<R extends UnknownRecord> = Store<R> | { store: Store<R> }\n/** @public */\nexport type StoreObjectRecordType<Context extends StoreObject<any>> =\n\tContext extends Store<infer R> ? R : Context extends { store: Store<infer R> } ? R : never\n\n/**\n * Free version of {@link Store.createComputedCache}.\n *\n * @example\n * ```ts\n * const myCache = createComputedCache('myCache', (editor: Editor, shape: TLShape) => {\n * return editor.getSomethingExpensive(shape)\n * })\n *\n * myCache.get(editor, shape.id)\n * ```\n *\n * @public\n */\nexport function createComputedCache<\n\tContext extends StoreObject<any>,\n\tResult,\n\tRecord extends StoreObjectRecordType<Context> = StoreObjectRecordType<Context>,\n>(\n\tname: string,\n\tderive: (context: Context, record: Record) => Result | undefined,\n\topts?: CreateComputedCacheOpts<Result, Record>\n) {\n\tconst cache = new WeakCache<Context, ComputedCache<Result, Record>>()\n\treturn {\n\t\tget(context: Context, id: IdOf<Record>) {\n\t\t\tconst computedCache = cache.get(context, () => {\n\t\t\t\tconst store = (context instanceof Store ? context : context.store) as Store<Record>\n\t\t\t\treturn store.createComputedCache(name, (record) => derive(context, record), opts)\n\t\t\t})\n\t\t\treturn computedCache.get(id)\n\t\t},\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { Atom, Reactor, Signal, atom, computed, reactor, transact } from '@tldraw/state'\nimport {\n\tWeakCache,\n\tassert,\n\tfilterEntries,\n\tgetOwnProperty,\n\tisEqual,\n\tobjectMapEntries,\n\tobjectMapKeys,\n\tobjectMapValues,\n\tthrottleToNextFrame,\n\tuniqueId,\n} from '@tldraw/utils'\nimport { AtomMap } from './AtomMap'\nimport { IdOf, RecordId, UnknownRecord } from './BaseRecord'\nimport { RecordScope } from './RecordType'\nimport { RecordsDiff, squashRecordDiffs } from './RecordsDiff'\nimport { StoreQueries } from './StoreQueries'\nimport { SerializedSchema, StoreSchema } from './StoreSchema'\nimport { StoreSideEffects } from './StoreSideEffects'\nimport { devFreeze } from './devFreeze'\n\n/** @public */\nexport type RecordFromId<K extends RecordId<UnknownRecord>> =\n\tK extends RecordId<infer R> ? R : never\n\n/**\n * A diff describing the changes to a collection.\n *\n * @public\n */\nexport interface CollectionDiff<T> {\n\tadded?: Set<T>\n\tremoved?: Set<T>\n}\n\n/** @public */\nexport type ChangeSource = 'user' | 'remote'\n\n/** @public */\nexport interface StoreListenerFilters {\n\tsource: ChangeSource | 'all'\n\tscope: RecordScope | 'all'\n}\n\n/**\n * An entry containing changes that originated either by user actions or remote changes.\n *\n * @public\n */\nexport interface HistoryEntry<R extends UnknownRecord = UnknownRecord> {\n\tchanges: RecordsDiff<R>\n\tsource: ChangeSource\n}\n\n/**\n * A function that will be called when the history changes.\n *\n * @public\n */\nexport type StoreListener<R extends UnknownRecord> = (entry: HistoryEntry<R>) => void\n\n/**\n * A record store is a collection of records of different types.\n *\n * @public\n */\nexport interface ComputedCache<Data, R extends UnknownRecord> {\n\tget(id: IdOf<R>): Data | undefined\n}\n\n/** @public */\nexport interface CreateComputedCacheOpts<Data, R extends UnknownRecord> {\n\tareRecordsEqual?(a: R, b: R): boolean\n\tareResultsEqual?(a: Data, b: Data): boolean\n}\n\n/**\n * A serialized snapshot of the record store's values.\n *\n * @public\n */\nexport type SerializedStore<R extends UnknownRecord> = Record<IdOf<R>, R>\n\n/** @public */\nexport interface StoreSnapshot<R extends UnknownRecord> {\n\tstore: SerializedStore<R>\n\tschema: SerializedSchema\n}\n\n/** @public */\nexport interface StoreValidator<R extends UnknownRecord> {\n\tvalidate(record: unknown): R\n\tvalidateUsingKnownGoodVersion?(knownGoodVersion: R, record: unknown): R\n}\n\n/** @public */\nexport type StoreValidators<R extends UnknownRecord> = {\n\t[K in R['typeName']]: StoreValidator<Extract<R, { typeName: K }>>\n}\n\n/** @public */\nexport interface StoreError {\n\terror: Error\n\tphase: 'initialize' | 'createRecord' | 'updateRecord' | 'tests'\n\trecordBefore?: unknown\n\trecordAfter: unknown\n\tisExistingValidationIssue: boolean\n}\n\n/** @internal */\nexport type StoreRecord<S extends Store<any>> = S extends Store<infer R> ? R : never\n\n/**\n * A store of records.\n *\n * @public\n */\nexport class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {\n\t/**\n\t * The random id of the store.\n\t */\n\tpublic readonly id: string\n\t/**\n\t * An AtomMap containing the stores records.\n\t *\n\t * @internal\n\t * @readonly\n\t */\n\tprivate readonly records: AtomMap<IdOf<R>, R>\n\n\t/**\n\t * An atom containing the store's history.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\treadonly history: Atom<number, RecordsDiff<R>> = atom('history', 0, {\n\t\thistoryLength: 1000,\n\t})\n\n\t/**\n\t * A StoreQueries instance for this store.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\treadonly query: StoreQueries<R>\n\n\t/**\n\t * A set containing listeners that have been added to this store.\n\t *\n\t * @internal\n\t */\n\tprivate listeners = new Set<{ onHistory: StoreListener<R>; filters: StoreListenerFilters }>()\n\n\t/**\n\t * An array of history entries that have not yet been flushed.\n\t *\n\t * @internal\n\t */\n\tprivate historyAccumulator = new HistoryAccumulator<R>()\n\n\t/**\n\t * A reactor that responds to changes to the history by squashing the accumulated history and\n\t * notifying listeners of the changes.\n\t *\n\t * @internal\n\t */\n\tprivate historyReactor: Reactor\n\n\t/**\n\t * Function to dispose of any in-flight timeouts.\n\t *\n\t * @internal\n\t */\n\tprivate cancelHistoryReactor(): void {\n\t\t/* noop */\n\t}\n\n\treadonly schema: StoreSchema<R, Props>\n\n\treadonly props: Props\n\n\tpublic readonly scopedTypes: { readonly [K in RecordScope]: ReadonlySet<R['typeName']> }\n\n\tpublic readonly sideEffects = new StoreSideEffects<R>(this)\n\n\tconstructor(config: {\n\t\tid?: string\n\t\t/** The store's initial data. */\n\t\tinitialData?: SerializedStore<R>\n\t\t/**\n\t\t * A map of validators for each record type. A record's validator will be called when the record\n\t\t * is created or updated. It should throw an error if the record is invalid.\n\t\t */\n\t\tschema: StoreSchema<R, Props>\n\t\tprops: Props\n\t}) {\n\t\tconst { initialData, schema, id } = config\n\n\t\tthis.id = id ?? uniqueId()\n\t\tthis.schema = schema\n\t\tthis.props = config.props\n\n\t\tif (initialData) {\n\t\t\tthis.records = new AtomMap(\n\t\t\t\t'store',\n\t\t\t\tobjectMapEntries(initialData).map(([id, record]) => [\n\t\t\t\t\tid,\n\t\t\t\t\tdevFreeze(this.schema.validateRecord(this, record, 'initialize', null)),\n\t\t\t\t])\n\t\t\t)\n\t\t} else {\n\t\t\tthis.records = new AtomMap('store')\n\t\t}\n\n\t\tthis.query = new StoreQueries<R>(this.records, this.history)\n\n\t\tthis.historyReactor = reactor(\n\t\t\t'Store.historyReactor',\n\t\t\t() => {\n\t\t\t\t// deref to make sure we're subscribed regardless of whether we need to propagate\n\t\t\t\tthis.history.get()\n\t\t\t\t// If we have accumulated history, flush it and update listeners\n\t\t\t\tthis._flushHistory()\n\t\t\t},\n\t\t\t{ scheduleEffect: (cb) => (this.cancelHistoryReactor = throttleToNextFrame(cb)) }\n\t\t)\n\t\tthis.scopedTypes = {\n\t\t\tdocument: new Set(\n\t\t\t\tobjectMapValues(this.schema.types)\n\t\t\t\t\t.filter((t) => t.scope === 'document')\n\t\t\t\t\t.map((t) => t.typeName)\n\t\t\t),\n\t\t\tsession: new Set(\n\t\t\t\tobjectMapValues(this.schema.types)\n\t\t\t\t\t.filter((t) => t.scope === 'session')\n\t\t\t\t\t.map((t) => t.typeName)\n\t\t\t),\n\t\t\tpresence: new Set(\n\t\t\t\tobjectMapValues(this.schema.types)\n\t\t\t\t\t.filter((t) => t.scope === 'presence')\n\t\t\t\t\t.map((t) => t.typeName)\n\t\t\t),\n\t\t}\n\t}\n\n\tpublic _flushHistory() {\n\t\t// If we have accumulated history, flush it and update listeners\n\t\tif (this.historyAccumulator.hasChanges()) {\n\t\t\tconst entries = this.historyAccumulator.flush()\n\t\t\tfor (const { changes, source } of entries) {\n\t\t\t\tlet instanceChanges = null as null | RecordsDiff<R>\n\t\t\t\tlet documentChanges = null as null | RecordsDiff<R>\n\t\t\t\tlet presenceChanges = null as null | RecordsDiff<R>\n\t\t\t\tfor (const { onHistory, filters } of this.listeners) {\n\t\t\t\t\tif (filters.source !== 'all' && filters.source !== source) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (filters.scope !== 'all') {\n\t\t\t\t\t\tif (filters.scope === 'document') {\n\t\t\t\t\t\t\tdocumentChanges ??= this.filterChangesByScope(changes, 'document')\n\t\t\t\t\t\t\tif (!documentChanges) continue\n\t\t\t\t\t\t\tonHistory({ changes: documentChanges, source })\n\t\t\t\t\t\t} else if (filters.scope === 'session') {\n\t\t\t\t\t\t\tinstanceChanges ??= this.filterChangesByScope(changes, 'session')\n\t\t\t\t\t\t\tif (!instanceChanges) continue\n\t\t\t\t\t\t\tonHistory({ changes: instanceChanges, source })\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpresenceChanges ??= this.filterChangesByScope(changes, 'presence')\n\t\t\t\t\t\t\tif (!presenceChanges) continue\n\t\t\t\t\t\t\tonHistory({ changes: presenceChanges, source })\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonHistory({ changes, source })\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdispose() {\n\t\tthis.cancelHistoryReactor()\n\t}\n\n\t/**\n\t * Filters out non-document changes from a diff. Returns null if there are no changes left.\n\t * @param change - the records diff\n\t * @param scope - the records scope\n\t * @returns\n\t */\n\tfilterChangesByScope(change: RecordsDiff<R>, scope: RecordScope) {\n\t\tconst result = {\n\t\t\tadded: filterEntries(change.added, (_, r) => this.scopedTypes[scope].has(r.typeName)),\n\t\t\tupdated: filterEntries(change.updated, (_, r) => this.scopedTypes[scope].has(r[1].typeName)),\n\t\t\tremoved: filterEntries(change.removed, (_, r) => this.scopedTypes[scope].has(r.typeName)),\n\t\t}\n\t\tif (\n\t\t\tObject.keys(result.added).length === 0 &&\n\t\t\tObject.keys(result.updated).length === 0 &&\n\t\t\tObject.keys(result.removed).length === 0\n\t\t) {\n\t\t\treturn null\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Update the history with a diff of changes.\n\t *\n\t * @param changes - The changes to add to the history.\n\t */\n\tprivate updateHistory(changes: RecordsDiff<R>): void {\n\t\tthis.historyAccumulator.add({\n\t\t\tchanges,\n\t\t\tsource: this.isMergingRemoteChanges ? 'remote' : 'user',\n\t\t})\n\t\tif (this.listeners.size === 0) {\n\t\t\tthis.historyAccumulator.clear()\n\t\t}\n\t\tthis.history.set(this.history.get() + 1, changes)\n\t}\n\n\tvalidate(phase: 'initialize' | 'createRecord' | 'updateRecord' | 'tests') {\n\t\tthis.allRecords().forEach((record) => this.schema.validateRecord(this, record, phase, null))\n\t}\n\n\t/**\n\t * Add some records to the store. It's an error if they already exist.\n\t *\n\t * @param records - The records to add.\n\t * @param phaseOverride - The phase override.\n\t * @public\n\t */\n\tput(records: R[], phaseOverride?: 'initialize'): void {\n\t\tthis.atomic(() => {\n\t\t\tconst updates: Record<IdOf<UnknownRecord>, [from: R, to: R]> = {}\n\t\t\tconst additions: Record<IdOf<UnknownRecord>, R> = {}\n\n\t\t\t// Iterate through all records, creating, updating or removing as needed\n\t\t\tlet record: R\n\n\t\t\t// There's a chance that, despite having records, all of the values are\n\t\t\t// identical to what they were before; and so we'd end up with an \"empty\"\n\t\t\t// history entry. Let's keep track of whether we've actually made any\n\t\t\t// changes (e.g. additions, deletions, or updates that produce a new value).\n\t\t\tlet didChange = false\n\n\t\t\tconst source = this.isMergingRemoteChanges ? 'remote' : 'user'\n\n\t\t\tfor (let i = 0, n = records.length; i < n; i++) {\n\t\t\t\trecord = records[i]\n\n\t\t\t\tconst initialValue = this.records.__unsafe__getWithoutCapture(record.id)\n\t\t\t\t// If we already have an atom for this record, update its value.\n\t\t\t\tif (initialValue) {\n\t\t\t\t\t// If we have a beforeUpdate callback, run it against the initial and next records\n\t\t\t\t\trecord = this.sideEffects.handleBeforeChange(initialValue, record, source)\n\n\t\t\t\t\t// Validate the record\n\t\t\t\t\tconst validated = this.schema.validateRecord(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\trecord,\n\t\t\t\t\t\tphaseOverride ?? 'updateRecord',\n\t\t\t\t\t\tinitialValue\n\t\t\t\t\t)\n\n\t\t\t\t\tif (validated === initialValue) continue\n\n\t\t\t\t\trecord = devFreeze(record)\n\t\t\t\t\tthis.records.set(record.id, record)\n\n\t\t\t\t\tdidChange = true\n\t\t\t\t\tupdates[record.id] = [initialValue, record]\n\t\t\t\t\tthis.addDiffForAfterEvent(initialValue, record)\n\t\t\t\t} else {\n\t\t\t\t\trecord = this.sideEffects.handleBeforeCreate(record, source)\n\n\t\t\t\t\tdidChange = true\n\n\t\t\t\t\t// If we don't have an atom, create one.\n\n\t\t\t\t\t// Validate the record\n\t\t\t\t\trecord = this.schema.validateRecord(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\trecord as R,\n\t\t\t\t\t\tphaseOverride ?? 'createRecord',\n\t\t\t\t\t\tnull\n\t\t\t\t\t)\n\n\t\t\t\t\t// freeze it\n\t\t\t\t\trecord = devFreeze(record)\n\n\t\t\t\t\t// Mark the change as a new addition.\n\t\t\t\t\tadditions[record.id] = record\n\t\t\t\t\tthis.addDiffForAfterEvent(null, record)\n\n\t\t\t\t\tthis.records.set(record.id, record)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we did change, update the history\n\t\t\tif (!didChange) return\n\t\t\tthis.updateHistory({\n\t\t\t\tadded: additions,\n\t\t\t\tupdated: updates,\n\t\t\t\tremoved: {} as Record<IdOf<R>, R>,\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Remove some records from the store via their ids.\n\t *\n\t * @param ids - The ids of the records to remove.\n\t * @public\n\t */\n\tremove(ids: IdOf<R>[]): void {\n\t\tthis.atomic(() => {\n\t\t\tconst toDelete = new Set<IdOf<R>>(ids)\n\t\t\tconst source = this.isMergingRemoteChanges ? 'remote' : 'user'\n\n\t\t\tif (this.sideEffects.isEnabled()) {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst record = this.records.__unsafe__getWithoutCapture(id)\n\t\t\t\t\tif (!record) continue\n\n\t\t\t\t\tif (this.sideEffects.handleBeforeDelete(record, source) === false) {\n\t\t\t\t\t\ttoDelete.delete(id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst actuallyDeleted = this.records.deleteMany(toDelete)\n\t\t\tif (actuallyDeleted.length === 0) return\n\n\t\t\tconst removed = {} as RecordsDiff<R>['removed']\n\t\t\tfor (const [id, record] of actuallyDeleted) {\n\t\t\t\tremoved[id] = record\n\t\t\t\tthis.addDiffForAfterEvent(record, null)\n\t\t\t}\n\n\t\t\t// Update the history with the removed records.\n\t\t\tthis.updateHistory({ added: {}, updated: {}, removed } as RecordsDiff<R>)\n\t\t})\n\t}\n\n\t/**\n\t * Get the value of a store record by its id.\n\t *\n\t * @param id - The id of the record to get.\n\t * @public\n\t */\n\tget<K extends IdOf<R>>(id: K): RecordFromId<K> | undefined {\n\t\treturn this.records.get(id) as RecordFromId<K> | undefined\n\t}\n\n\t/**\n\t * Get the value of a store record by its id without updating its epoch.\n\t *\n\t * @param id - The id of the record to get.\n\t * @public\n\t */\n\tunsafeGetWithoutCapture<K extends IdOf<R>>(id: K): RecordFromId<K> | undefined {\n\t\treturn this.records.__unsafe__getWithoutCapture(id) as RecordFromId<K> | undefined\n\t}\n\n\t/**\n\t * Creates a JSON payload from the record store.\n\t *\n\t * @param scope - The scope of records to serialize. Defaults to 'document'.\n\t * @returns The record store snapshot as a JSON payload.\n\t */\n\tserialize(scope: RecordScope | 'all' = 'document'): SerializedStore<R> {\n\t\tconst result = {} as SerializedStore<R>\n\t\tfor (const [id, record] of this.records) {\n\t\t\tif (scope === 'all' || this.scopedTypes[scope].has(record.typeName)) {\n\t\t\t\tresult[id as IdOf<R>] = record\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Get a serialized snapshot of the store and its schema.\n\t *\n\t * ```ts\n\t * const snapshot = store.getStoreSnapshot()\n\t * store.loadStoreSnapshot(snapshot)\n\t * ```\n\t *\n\t * @param scope - The scope of records to serialize. Defaults to 'document'.\n\t *\n\t * @public\n\t */\n\tgetStoreSnapshot(scope: RecordScope | 'all' = 'document'): StoreSnapshot<R> {\n\t\treturn {\n\t\t\tstore: this.serialize(scope),\n\t\t\tschema: this.schema.serialize(),\n\t\t}\n\t}\n\n\t/**\n\t * Migrate a serialized snapshot of the store and its schema.\n\t *\n\t * ```ts\n\t * const snapshot = store.getStoreSnapshot()\n\t * store.migrateSnapshot(snapshot)\n\t * ```\n\t *\n\t * @param snapshot - The snapshot to load.\n\t * @public\n\t */\n\tmigrateSnapshot(snapshot: StoreSnapshot<R>): StoreSnapshot<R> {\n\t\tconst migrationResult = this.schema.migrateStoreSnapshot(snapshot)\n\n\t\tif (migrationResult.type === 'error') {\n\t\t\tthrow new Error(`Failed to migrate snapshot: ${migrationResult.reason}`)\n\t\t}\n\n\t\treturn {\n\t\t\tstore: migrationResult.value,\n\t\t\tschema: this.schema.serialize(),\n\t\t}\n\t}\n\n\t/**\n\t * Load a serialized snapshot.\n\t *\n\t * ```ts\n\t * const snapshot = store.getStoreSnapshot()\n\t * store.loadStoreSnapshot(snapshot)\n\t * ```\n\t *\n\t * @param snapshot - The snapshot to load.\n\t * @public\n\t */\n\tloadStoreSnapshot(snapshot: StoreSnapshot<R>): void {\n\t\tconst migrationResult = this.schema.migrateStoreSnapshot(snapshot)\n\n\t\tif (migrationResult.type === 'error') {\n\t\t\tthrow new Error(`Failed to migrate snapshot: ${migrationResult.reason}`)\n\t\t}\n\n\t\tconst prevSideEffectsEnabled = this.sideEffects.isEnabled()\n\t\ttry {\n\t\t\tthis.sideEffects.setIsEnabled(false)\n\t\t\tthis.atomic(() => {\n\t\t\t\tthis.clear()\n\t\t\t\tthis.put(Object.values(migrationResult.value))\n\t\t\t\tthis.ensureStoreIsUsable()\n\t\t\t})\n\t\t} finally {\n\t\t\tthis.sideEffects.setIsEnabled(prevSideEffectsEnabled)\n\t\t}\n\t}\n\n\t/**\n\t * Get an array of all values in the store.\n\t *\n\t * @returns An array of all values in the store.\n\t * @public\n\t */\n\tallRecords(): R[] {\n\t\treturn Array.from(this.records.values())\n\t}\n\n\t/**\n\t * Removes all records from the store.\n\t *\n\t * @public\n\t */\n\tclear(): void {\n\t\tthis.remove(Array.from(this.records.keys()))\n\t}\n\n\t/**\n\t * Update a record. To update multiple records at once, use the `update` method of the\n\t * `TypedStore` class.\n\t *\n\t * @param id - The id of the record to update.\n\t * @param updater - A function that updates the record.\n\t */\n\tupdate<K extends IdOf<R>>(id: K, updater: (record: RecordFromId<K>) => RecordFromId<K>) {\n\t\tconst existing = this.unsafeGetWithoutCapture(id)\n\t\tif (!existing) {\n\t\t\tconsole.error(`Record ${id} not found. This is probably an error`)\n\t\t\treturn\n\t\t}\n\n\t\tthis.put([updater(existing) as any])\n\t}\n\n\t/**\n\t * Get whether the record store has a id.\n\t *\n\t * @param id - The id of the record to check.\n\t * @public\n\t */\n\thas<K extends IdOf<R>>(id: K): boolean {\n\t\treturn this.records.has(id)\n\t}\n\n\t/**\n\t * Add a new listener to the store.\n\t *\n\t * @param onHistory - The listener to call when the store updates.\n\t * @param filters - Filters to apply to the listener.\n\t * @returns A function to remove the listener.\n\t */\n\tlisten(onHistory: StoreListener<R>, filters?: Partial<StoreListenerFilters>) {\n\t\t// flush history so that this listener's history starts from exactly now\n\t\tthis._flushHistory()\n\n\t\tconst listener = {\n\t\t\tonHistory,\n\t\t\tfilters: {\n\t\t\t\tsource: filters?.source ?? 'all',\n\t\t\t\tscope: filters?.scope ?? 'all',\n\t\t\t},\n\t\t}\n\n\t\tif (!this.historyReactor.scheduler.isActivelyListening) {\n\t\t\tthis.historyReactor.start()\n\t\t\tthis.historyReactor.scheduler.execute()\n\t\t}\n\n\t\tthis.listeners.add(listener)\n\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener)\n\n\t\t\tif (this.listeners.size === 0) {\n\t\t\t\tthis.historyReactor.stop()\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isMergingRemoteChanges = false\n\n\t/**\n\t * Merge changes from a remote source\n\t *\n\t * @param fn - A function that merges the external changes.\n\t * @public\n\t */\n\tmergeRemoteChanges(fn: () => void) {\n\t\tif (this.isMergingRemoteChanges) {\n\t\t\treturn fn()\n\t\t}\n\n\t\tif (this._isInAtomicOp) {\n\t\t\tthrow new Error('Cannot merge remote changes while in atomic operation')\n\t\t}\n\n\t\ttry {\n\t\t\tthis.atomic(fn, true, true)\n\t\t} finally {\n\t\t\tthis.ensureStoreIsUsable()\n\t\t}\n\t}\n\n\t/**\n\t * Run `fn` and return a {@link RecordsDiff} of the changes that occurred as a result.\n\t */\n\textractingChanges(fn: () => void): RecordsDiff<R> {\n\t\tconst changes: Array<RecordsDiff<R>> = []\n\t\tconst dispose = this.historyAccumulator.addInterceptor((entry) => changes.push(entry.changes))\n\t\ttry {\n\t\t\ttransact(fn)\n\t\t\treturn squashRecordDiffs(changes)\n\t\t} finally {\n\t\t\tdispose()\n\t\t}\n\t}\n\n\tapplyDiff(\n\t\tdiff: RecordsDiff<R>,\n\t\t{\n\t\t\trunCallbacks = true,\n\t\t\tignoreEphemeralKeys = false,\n\t\t}: { runCallbacks?: boolean; ignoreEphemeralKeys?: boolean } = {}\n\t) {\n\t\tthis.atomic(() => {\n\t\t\tconst toPut = objectMapValues(diff.added)\n\n\t\t\tfor (const [_from, to] of objectMapValues(diff.updated)) {\n\t\t\t\tconst type = this.schema.getType(to.typeName)\n\t\t\t\tif (ignoreEphemeralKeys && type.ephemeralKeySet.size) {\n\t\t\t\t\tconst existing = this.get(to.id)\n\t\t\t\t\tif (!existing) {\n\t\t\t\t\t\ttoPut.push(to)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tlet changed: R | null = null\n\t\t\t\t\tfor (const [key, value] of Object.entries(to)) {\n\t\t\t\t\t\tif (type.ephemeralKeySet.has(key) || Object.is(value, getOwnProperty(existing, key))) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!changed) changed = { ...existing } as R\n\t\t\t\t\t\t;(changed as any)[key] = value\n\t\t\t\t\t}\n\t\t\t\t\tif (changed) toPut.push(changed)\n\t\t\t\t} else {\n\t\t\t\t\ttoPut.push(to)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst toRemove = objectMapKeys(diff.removed)\n\t\t\tif (toPut.length) {\n\t\t\t\tthis.put(toPut)\n\t\t\t}\n\t\t\tif (toRemove.length) {\n\t\t\t\tthis.remove(toRemove)\n\t\t\t}\n\t\t}, runCallbacks)\n\t}\n\n\t/**\n\t * Create a cache based on values in the store. Pass in a function that takes and ID and a\n\t * signal for the underlying record. Return a signal (usually a computed) for the cached value.\n\t * For simple derivations, use {@link Store.createComputedCache}. This function is useful if you\n\t * need more precise control over intermediate values.\n\t */\n\tcreateCache<Result, Record extends R = R>(\n\t\tcreate: (id: IdOf<Record>, recordSignal: Signal<R>) => Signal<Result>\n\t) {\n\t\tconst cache = new WeakCache<Atom<any>, Signal<Result>>()\n\t\treturn {\n\t\t\tget: (id: IdOf<Record>) => {\n\t\t\t\tconst atom = this.records.getAtom(id)\n\t\t\t\tif (!atom) return undefined\n\t\t\t\treturn cache.get(atom, () => create(id, atom as Signal<R>)).get()\n\t\t\t},\n\t\t}\n\t}\n\n\t/**\n\t * Create a computed cache.\n\t *\n\t * @param name - The name of the derivation cache.\n\t * @param derive - A function used to derive the value of the cache.\n\t * @param opts - Options for the computed cache.\n\t * @public\n\t */\n\tcreateComputedCache<Result, Record extends R = R>(\n\t\tname: string,\n\t\tderive: (record: Record) => Result | undefined,\n\t\topts?: CreateComputedCacheOpts<Result, Record>\n\t): ComputedCache<Result, Record> {\n\t\treturn this.createCache((id, record) => {\n\t\t\tconst recordSignal = opts?.areRecordsEqual\n\t\t\t\t? computed(`${name}:${id}:isEqual`, () => record.get(), { isEqual: opts.areRecordsEqual })\n\t\t\t\t: record\n\n\t\t\treturn computed<Result | undefined>(\n\t\t\t\tname + ':' + id,\n\t\t\t\t() => {\n\t\t\t\t\treturn derive(recordSignal.get() as Record)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tisEqual: opts?.areResultsEqual,\n\t\t\t\t}\n\t\t\t)\n\t\t})\n\t}\n\n\tprivate _integrityChecker?: () => void | undefined\n\n\t/** @internal */\n\tensureStoreIsUsable() {\n\t\tthis.atomic(() => {\n\t\t\tthis._integrityChecker ??= this.schema.createIntegrityChecker(this)\n\t\t\tthis._integrityChecker?.()\n\t\t})\n\t}\n\n\tprivate _isPossiblyCorrupted = false\n\t/** @internal */\n\tmarkAsPossiblyCorrupted() {\n\t\tthis._isPossiblyCorrupted = true\n\t}\n\t/** @internal */\n\tisPossiblyCorrupted() {\n\t\treturn this._isPossiblyCorrupted\n\t}\n\n\tprivate pendingAfterEvents: Map<IdOf<R>, { before: R | null; after: R | null }> | null = null\n\tprivate addDiffForAfterEvent(before: R | null, after: R | null) {\n\t\tassert(this.pendingAfterEvents, 'must be in event operation')\n\t\tif (before === after) return\n\t\tif (before && after) assert(before.id === after.id)\n\t\tif (!before && !after) return\n\t\tconst id = (before || after)!.id\n\t\tconst existing = this.pendingAfterEvents.get(id)\n\t\tif (existing) {\n\t\t\texisting.after = after\n\t\t} else {\n\t\t\tthis.pendingAfterEvents.set(id, { before, after })\n\t\t}\n\t}\n\tprivate flushAtomicCallbacks(isMergingRemoteChanges: boolean) {\n\t\tlet updateDepth = 0\n\t\tlet source: ChangeSource = isMergingRemoteChanges ? 'remote' : 'user'\n\t\twhile (this.pendingAfterEvents) {\n\t\t\tconst events = this.pendingAfterEvents\n\t\t\tthis.pendingAfterEvents = null\n\n\t\t\tif (!this.sideEffects.isEnabled()) continue\n\n\t\t\tupdateDepth++\n\t\t\tif (updateDepth > 100) {\n\t\t\t\tthrow new Error('Maximum store update depth exceeded, bailing out')\n\t\t\t}\n\n\t\t\tfor (const { before, after } of events.values()) {\n\t\t\t\tif (before && after && before !== after && !isEqual(before, after)) {\n\t\t\t\t\tthis.sideEffects.handleAfterChange(before, after, source)\n\t\t\t\t} else if (before && !after) {\n\t\t\t\t\tthis.sideEffects.handleAfterDelete(before, source)\n\t\t\t\t} else if (!before && after) {\n\t\t\t\t\tthis.sideEffects.handleAfterCreate(after, source)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!this.pendingAfterEvents) {\n\t\t\t\tthis.sideEffects.handleOperationComplete(source)\n\t\t\t} else {\n\t\t\t\t// if the side effects triggered by a remote operation resulted in more effects,\n\t\t\t\t// those extra effects should not be marked as originating remotely.\n\t\t\t\tsource = 'user'\n\t\t\t}\n\t\t}\n\t}\n\tprivate _isInAtomicOp = false\n\t/** @internal */\n\tatomic<T>(fn: () => T, runCallbacks = true, isMergingRemoteChanges = false): T {\n\t\treturn transact(() => {\n\t\t\tif (this._isInAtomicOp) {\n\t\t\t\tif (!this.pendingAfterEvents) this.pendingAfterEvents = new Map()\n\t\t\t\tconst prevSideEffectsEnabled = this.sideEffects.isEnabled()\n\t\t\t\tassert(!isMergingRemoteChanges, 'cannot call mergeRemoteChanges while in atomic operation')\n\t\t\t\ttry {\n\t\t\t\t\t// if we are in an atomic context with side effects ON allow switching before* callbacks OFF.\n\t\t\t\t\t// but don't allow switching them ON if they had been marked OFF before.\n\t\t\t\t\tif (prevSideEffectsEnabled && !runCallbacks) {\n\t\t\t\t\t\tthis.sideEffects.setIsEnabled(false)\n\t\t\t\t\t}\n\t\t\t\t\treturn fn()\n\t\t\t\t} finally {\n\t\t\t\t\tthis.sideEffects.setIsEnabled(prevSideEffectsEnabled)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.pendingAfterEvents = new Map()\n\t\t\tconst prevSideEffectsEnabled = this.sideEffects.isEnabled()\n\t\t\tthis.sideEffects.setIsEnabled(runCallbacks ?? prevSideEffectsEnabled)\n\t\t\tthis._isInAtomicOp = true\n\n\t\t\tif (isMergingRemoteChanges) {\n\t\t\t\tthis.isMergingRemoteChanges = true\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = fn()\n\t\t\t\tthis.isMergingRemoteChanges = false\n\n\t\t\t\tthis.flushAtomicCallbacks(isMergingRemoteChanges)\n\n\t\t\t\treturn result\n\t\t\t} finally {\n\t\t\t\tthis.pendingAfterEvents = null\n\t\t\t\tthis.sideEffects.setIsEnabled(prevSideEffectsEnabled)\n\t\t\t\tthis._isInAtomicOp = false\n\t\t\t\tthis.isMergingRemoteChanges = false\n\t\t\t}\n\t\t})\n\t}\n\n\t/** @internal */\n\taddHistoryInterceptor(fn: (entry: HistoryEntry<R>, source: ChangeSource) => void) {\n\t\treturn this.historyAccumulator.addInterceptor((entry) =>\n\t\t\tfn(entry, this.isMergingRemoteChanges ? 'remote' : 'user')\n\t\t)\n\t}\n}\n\n/**\n * Collect all history entries by their adjacent sources.\n * For example, [user, user, remote, remote, user] would result in [user, remote, user],\n * with adjacent entries of the same source squashed into a single entry.\n *\n * @param entries - The array of history entries.\n * @returns A map of history entries by their sources.\n * @public\n */\nfunction squashHistoryEntries<T extends UnknownRecord>(\n\tentries: HistoryEntry<T>[]\n): HistoryEntry<T>[] {\n\tif (entries.length === 0) return []\n\n\tconst chunked: HistoryEntry<T>[][] = []\n\tlet chunk: HistoryEntry<T>[] = [entries[0]]\n\tlet entry: HistoryEntry<T>\n\n\tfor (let i = 1, n = entries.length; i < n; i++) {\n\t\tentry = entries[i]\n\t\tif (chunk[0].source !== entry.source) {\n\t\t\tchunked.push(chunk)\n\t\t\tchunk = []\n\t\t}\n\t\tchunk.push(entry)\n\t}\n\t// Push the last chunk\n\tchunked.push(chunk)\n\n\treturn devFreeze(\n\t\tchunked.map((chunk) => ({\n\t\t\tsource: chunk[0].source,\n\t\t\tchanges: squashRecordDiffs(chunk.map((e) => e.changes)),\n\t\t}))\n\t)\n}\n\nclass HistoryAccumulator<T extends UnknownRecord> {\n\tprivate _history: HistoryEntry<T>[] = []\n\n\tprivate _interceptors: Set<(entry: HistoryEntry<T>) => void> = new Set()\n\n\taddInterceptor(fn: (entry: HistoryEntry<T>) => void) {\n\t\tthis._interceptors.add(fn)\n\t\treturn () => {\n\t\t\tthis._interceptors.delete(fn)\n\t\t}\n\t}\n\n\tadd(entry: HistoryEntry<T>) {\n\t\tthis._history.push(entry)\n\t\tfor (const interceptor of this._interceptors) {\n\t\t\tinterceptor(entry)\n\t\t}\n\t}\n\n\tflush() {\n\t\tconst history = squashHistoryEntries(this._history)\n\t\tthis._history = []\n\t\treturn history\n\t}\n\n\tclear() {\n\t\tthis._history = []\n\t}\n\n\thasChanges() {\n\t\treturn this._history.length > 0\n\t}\n}\n\n/** @public */\nexport type StoreObject<R extends UnknownRecord> = Store<R> | { store: Store<R> }\n/** @public */\nexport type StoreObjectRecordType<Context extends StoreObject<any>> =\n\tContext extends Store<infer R> ? R : Context extends { store: Store<infer R> } ? R : never\n\n/**\n * Free version of {@link Store.createComputedCache}.\n *\n * @example\n * ```ts\n * const myCache = createComputedCache('myCache', (editor: Editor, shape: TLShape) => {\n * return editor.getSomethingExpensive(shape)\n * })\n *\n * myCache.get(editor, shape.id)\n * ```\n *\n * @public\n */\nexport function createComputedCache<\n\tContext extends StoreObject<any>,\n\tResult,\n\tRecord extends StoreObjectRecordType<Context> = StoreObjectRecordType<Context>,\n>(\n\tname: string,\n\tderive: (context: Context, record: Record) => Result | undefined,\n\topts?: CreateComputedCacheOpts<Result, Record>\n) {\n\tconst cache = new WeakCache<Context, ComputedCache<Result, Record>>()\n\treturn {\n\t\tget(context: Context, id: IdOf<Record>) {\n\t\t\tconst computedCache = cache.get(context, () => {\n\t\t\t\tconst store = (context instanceof Store ? context : context.store) as Store<Record>\n\t\t\t\treturn store.createComputedCache(name, (record) => derive(context, record), opts)\n\t\t\t})\n\t\t\treturn computedCache.get(id)\n\t\t},\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["id", "atom", "prevSideEffectsEnabled", "chunk"]
|
|
7
7
|
}
|