@tldraw/store
Advanced tools
Comparing version 2.0.0-canary.faecd88220a7 to 2.0.0-canary.fc36d5b57759
@@ -0,1 +1,64 @@ | ||
# v2.0.0-alpha.14 (Tue Jul 04 2023) | ||
### Release Notes | ||
#### [fix] mutating `snapshot` in `migrateStoreSnapshot` ([#1663](https://github.com/tldraw/tldraw/pull/1663)) | ||
- [@tldraw/store] Fixed a bug that would cause `Store.migrateStoreSnapshot` to mutate its `snapshot` argument. | ||
--- | ||
#### 🐛 Bug Fix | ||
- [fix] mutating `snapshot` in `migrateStoreSnapshot` [#1663](https://github.com/tldraw/tldraw/pull/1663) ([@steveruizok](https://github.com/steveruizok)) | ||
#### Authors: 1 | ||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok)) | ||
--- | ||
# v2.0.0-alpha.13 (Wed Jun 28 2023) | ||
### Release Notes | ||
#### [improvement] store snapshot types ([#1657](https://github.com/tldraw/tldraw/pull/1657)) | ||
- [dev] Rename `StoreSnapshot` to `SerializedStore` | ||
- [dev] Create new `StoreSnapshot` as type related to `getSnapshot`/`loadSnapshot` | ||
#### tlschema cleanup ([#1509](https://github.com/tldraw/tldraw/pull/1509)) | ||
- [editor] Remove `app.createShapeId` | ||
- [tlschema] Cleans up exports | ||
#### Rename tlstore to store ([#1507](https://github.com/tldraw/tldraw/pull/1507)) | ||
- Replace @tldraw/tlstore with @tldraw/store | ||
--- | ||
#### 💥 Breaking Change | ||
- [tweak] migrate store snapshot arguments [#1659](https://github.com/tldraw/tldraw/pull/1659) ([@steveruizok](https://github.com/steveruizok)) | ||
- [improvement] store snapshot types [#1657](https://github.com/tldraw/tldraw/pull/1657) ([@steveruizok](https://github.com/steveruizok)) | ||
- Independent instance state persistence [#1493](https://github.com/tldraw/tldraw/pull/1493) ([@ds300](https://github.com/ds300)) | ||
- tlschema cleanup [#1509](https://github.com/tldraw/tldraw/pull/1509) ([@steveruizok](https://github.com/steveruizok)) | ||
- Rename tlstore to store [#1507](https://github.com/tldraw/tldraw/pull/1507) ([@steveruizok](https://github.com/steveruizok)) | ||
#### ⚠️ Pushed to `main` | ||
- update lazyrepo ([@ds300](https://github.com/ds300)) | ||
#### 🔩 Dependency Updates | ||
- Incorporate signia as @tldraw/state [#1620](https://github.com/tldraw/tldraw/pull/1620) ([@steveruizok](https://github.com/steveruizok) [@ds300](https://github.com/ds300)) | ||
#### Authors: 2 | ||
- David Sheldrick ([@ds300](https://github.com/ds300)) | ||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok)) | ||
--- | ||
# v2.0.0-alpha.12 (Mon Apr 03 2023) | ||
@@ -2,0 +65,0 @@ |
@@ -395,2 +395,9 @@ import { Atom } from '@tldraw/state'; | ||
/** | ||
* A serialized snapshot of the record store's values. | ||
* | ||
* @public | ||
*/ | ||
export declare type SerializedStore<R extends UnknownRecord> = Record<IdOf<R>, R>; | ||
/** | ||
* Squash a collection of diffs into a single diff. | ||
@@ -439,3 +446,3 @@ * | ||
/** The store's initial data. */ | ||
initialData?: StoreSnapshot<R>; | ||
initialData?: SerializedStore<R>; | ||
/** | ||
@@ -527,3 +534,3 @@ * A map of validators for each record type. A record's validator will be called when the record | ||
*/ | ||
serialize: (scope?: 'all' | RecordScope) => StoreSnapshot<R>; | ||
serialize: (scope?: 'all' | RecordScope) => SerializedStore<R>; | ||
/** | ||
@@ -540,6 +547,3 @@ * Get a serialized snapshot of the store and its schema. | ||
*/ | ||
getSnapshot(scope?: 'all' | RecordScope): { | ||
store: StoreSnapshot<R>; | ||
schema: SerializedSchema; | ||
}; | ||
getSnapshot(scope?: 'all' | RecordScope): StoreSnapshot<R>; | ||
/** | ||
@@ -557,6 +561,3 @@ * Load a serialized snapshot. | ||
*/ | ||
loadSnapshot(snapshot: { | ||
store: StoreSnapshot<R>; | ||
schema: SerializedSchema; | ||
}): void; | ||
loadSnapshot(snapshot: StoreSnapshot<R>): void; | ||
/** | ||
@@ -748,3 +749,3 @@ * Get an array of all values in the store. | ||
migratePersistedRecord(record: R, persistedSchema: SerializedSchema, direction?: 'down' | 'up'): MigrationResult<R>; | ||
migrateStoreSnapshot(storeSnapshot: StoreSnapshot<R>, persistedSchema: SerializedSchema): MigrationResult<StoreSnapshot<R>>; | ||
migrateStoreSnapshot(snapshot: StoreSnapshot<R>): MigrationResult<SerializedStore<R>>; | ||
/* Excluded from this release type: createIntegrityChecker */ | ||
@@ -770,8 +771,7 @@ serialize(): SerializedSchema; | ||
/** | ||
* A serialized snapshot of the record store's values. | ||
* | ||
* @public | ||
*/ | ||
export declare type StoreSnapshot<R extends UnknownRecord> = Record<IdOf<R>, R>; | ||
/** @public */ | ||
export declare type StoreSnapshot<R extends UnknownRecord> = { | ||
store: SerializedStore<R>; | ||
schema: SerializedSchema; | ||
}; | ||
@@ -778,0 +778,0 @@ /** @public */ |
@@ -387,3 +387,3 @@ "use strict"; | ||
loadSnapshot(snapshot) { | ||
const migrationResult = this.schema.migrateStoreSnapshot(snapshot.store, snapshot.schema); | ||
const migrationResult = this.schema.migrateStoreSnapshot(snapshot); | ||
if (migrationResult.type === "error") { | ||
@@ -390,0 +390,0 @@ throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`); |
@@ -110,9 +110,10 @@ "use strict"; | ||
} | ||
migrateStoreSnapshot(storeSnapshot, persistedSchema) { | ||
migrateStoreSnapshot(snapshot) { | ||
let { store } = snapshot; | ||
const migrations = this.options.snapshotMigrations; | ||
if (!migrations) { | ||
return { type: "success", value: storeSnapshot }; | ||
return { type: "success", value: store }; | ||
} | ||
const ourStoreVersion = migrations.currentVersion; | ||
const persistedStoreVersion = persistedSchema.storeVersion ?? 0; | ||
const persistedStoreVersion = snapshot.schema.storeVersion ?? 0; | ||
if (ourStoreVersion < persistedStoreVersion) { | ||
@@ -123,3 +124,3 @@ return { type: "error", reason: import_migrate.MigrationFailureReason.TargetVersionTooOld }; | ||
const result = (0, import_migrate.migrate)({ | ||
value: storeSnapshot, | ||
value: store, | ||
migrations, | ||
@@ -132,7 +133,7 @@ fromVersion: persistedStoreVersion, | ||
} | ||
storeSnapshot = result.value; | ||
store = result.value; | ||
} | ||
const updated = []; | ||
for (const r of (0, import_utils.objectMapValues)(storeSnapshot)) { | ||
const result = this.migratePersistedRecord(r, persistedSchema); | ||
for (const r of (0, import_utils.objectMapValues)(store)) { | ||
const result = this.migratePersistedRecord(r, snapshot.schema); | ||
if (result.type === "error") { | ||
@@ -145,8 +146,8 @@ return result; | ||
if (updated.length) { | ||
storeSnapshot = { ...storeSnapshot }; | ||
store = { ...store }; | ||
for (const r of updated) { | ||
storeSnapshot[r.id] = r; | ||
store[r.id] = r; | ||
} | ||
} | ||
return { type: "success", value: storeSnapshot }; | ||
return { type: "success", value: store }; | ||
} | ||
@@ -153,0 +154,0 @@ /** @internal */ |
{ | ||
"name": "@tldraw/store", | ||
"description": "A tiny little drawing app (store).", | ||
"version": "2.0.0-canary.faecd88220a7", | ||
"version": "2.0.0-canary.fc36d5b57759", | ||
"packageManager": "yarn@3.5.0", | ||
@@ -45,6 +45,6 @@ "author": { | ||
"dependencies": { | ||
"@tldraw/state": "2.0.0-canary.faecd88220a7", | ||
"@tldraw/utils": "2.0.0-canary.faecd88220a7", | ||
"@tldraw/state": "2.0.0-canary.fc36d5b57759", | ||
"@tldraw/utils": "2.0.0-canary.fc36d5b57759", | ||
"lodash.isequal": "^4.5.0", | ||
"nanoid": "4.0.2" | ||
"nanoid": "^3.3.6" | ||
}, | ||
@@ -66,3 +66,3 @@ "devDependencies": { | ||
"transformIgnorePatterns": [ | ||
"node_modules/(?!(nanoid|escape-string-regexp)/)" | ||
"node_modules/(?!(nanoid)/)" | ||
] | ||
@@ -69,0 +69,0 @@ }, |
@@ -10,2 +10,3 @@ export type { BaseRecord, IdOf, RecordId, UnknownRecord } from './lib/BaseRecord' | ||
RecordsDiff, | ||
SerializedStore, | ||
StoreError, | ||
@@ -12,0 +13,0 @@ StoreListener, |
@@ -76,5 +76,11 @@ import { Atom, Computed, Reactor, atom, computed, reactor, transact } from '@tldraw/state' | ||
*/ | ||
export type StoreSnapshot<R extends UnknownRecord> = Record<IdOf<R>, R> | ||
export type SerializedStore<R extends UnknownRecord> = Record<IdOf<R>, R> | ||
/** @public */ | ||
export type StoreSnapshot<R extends UnknownRecord> = { | ||
store: SerializedStore<R> | ||
schema: SerializedSchema | ||
} | ||
/** @public */ | ||
export type StoreValidator<R extends UnknownRecord> = { | ||
@@ -167,3 +173,3 @@ validate: (record: unknown) => R | ||
/** The store's initial data. */ | ||
initialData?: StoreSnapshot<R> | ||
initialData?: SerializedStore<R> | ||
/** | ||
@@ -508,4 +514,4 @@ * A map of validators for each record type. A record's validator will be called when the record | ||
*/ | ||
serialize = (scope: RecordScope | 'all' = 'document'): StoreSnapshot<R> => { | ||
const result = {} as StoreSnapshot<R> | ||
serialize = (scope: RecordScope | 'all' = 'document'): SerializedStore<R> => { | ||
const result = {} as SerializedStore<R> | ||
for (const [id, atom] of objectMapEntries(this.atoms.value)) { | ||
@@ -531,3 +537,3 @@ const record = atom.value | ||
*/ | ||
getSnapshot(scope: RecordScope | 'all' = 'document') { | ||
getSnapshot(scope: RecordScope | 'all' = 'document'): StoreSnapshot<R> { | ||
return { | ||
@@ -551,4 +557,4 @@ store: this.serialize(scope), | ||
*/ | ||
loadSnapshot(snapshot: { store: StoreSnapshot<R>; schema: SerializedSchema }): void { | ||
const migrationResult = this.schema.migrateStoreSnapshot(snapshot.store, snapshot.schema) | ||
loadSnapshot(snapshot: StoreSnapshot<R>): void { | ||
const migrationResult = this.schema.migrateStoreSnapshot(snapshot) | ||
@@ -555,0 +561,0 @@ if (migrationResult.type === 'error') { |
import { getOwnProperty, objectMapValues } from '@tldraw/utils' | ||
import { IdOf, UnknownRecord } from './BaseRecord' | ||
import { RecordType } from './RecordType' | ||
import { Store, StoreSnapshot } from './Store' | ||
import { SerializedStore, Store, StoreSnapshot } from './Store' | ||
import { | ||
@@ -191,13 +191,12 @@ MigrationFailureReason, | ||
migrateStoreSnapshot( | ||
storeSnapshot: StoreSnapshot<R>, | ||
persistedSchema: SerializedSchema | ||
): MigrationResult<StoreSnapshot<R>> { | ||
migrateStoreSnapshot(snapshot: StoreSnapshot<R>): MigrationResult<SerializedStore<R>> { | ||
let { store } = snapshot | ||
const migrations = this.options.snapshotMigrations | ||
if (!migrations) { | ||
return { type: 'success', value: storeSnapshot } | ||
return { type: 'success', value: store } | ||
} | ||
// apply store migrations first | ||
const ourStoreVersion = migrations.currentVersion | ||
const persistedStoreVersion = persistedSchema.storeVersion ?? 0 | ||
const persistedStoreVersion = snapshot.schema.storeVersion ?? 0 | ||
@@ -209,4 +208,4 @@ if (ourStoreVersion < persistedStoreVersion) { | ||
if (ourStoreVersion > persistedStoreVersion) { | ||
const result = migrate<StoreSnapshot<R>>({ | ||
value: storeSnapshot, | ||
const result = migrate<SerializedStore<R>>({ | ||
value: store, | ||
migrations, | ||
@@ -220,8 +219,8 @@ fromVersion: persistedStoreVersion, | ||
} | ||
storeSnapshot = result.value | ||
store = result.value | ||
} | ||
const updated: R[] = [] | ||
for (const r of objectMapValues(storeSnapshot)) { | ||
const result = this.migratePersistedRecord(r, persistedSchema) | ||
for (const r of objectMapValues(store)) { | ||
const result = this.migratePersistedRecord(r, snapshot.schema) | ||
if (result.type === 'error') { | ||
@@ -234,8 +233,8 @@ return result | ||
if (updated.length) { | ||
storeSnapshot = { ...storeSnapshot } | ||
store = { ...store } | ||
for (const r of updated) { | ||
storeSnapshot[r.id as IdOf<R>] = r | ||
store[r.id as IdOf<R>] = r | ||
} | ||
} | ||
return { type: 'success', value: storeSnapshot } | ||
return { type: 'success', value: store } | ||
} | ||
@@ -242,0 +241,0 @@ |
import { MigrationFailureReason } from '../migrate' | ||
import { StoreSnapshot } from '../Store' | ||
import { SerializedStore } from '../Store' | ||
import { testSchemaV0 } from './testSchema.v0' | ||
@@ -308,3 +308,3 @@ import { testSchemaV1 } from './testSchema.v1' | ||
test('migrating a whole store snapshot works', () => { | ||
const snapshot: StoreSnapshot<any> = { | ||
const serializedStore: SerializedStore<any> = { | ||
'user-1': { | ||
@@ -333,3 +333,6 @@ id: 'user-1', | ||
const result = testSchemaV1.migrateStoreSnapshot(snapshot, serializedV0Schenma) | ||
const result = testSchemaV1.migrateStoreSnapshot({ | ||
store: serializedStore, | ||
schema: serializedV0Schenma, | ||
}) | ||
@@ -336,0 +339,0 @@ if (result.type !== 'success') { |
@@ -1,2 +0,2 @@ | ||
import { assert } from '@tldraw/utils' | ||
import assert from 'assert' | ||
import { BaseRecord, RecordId } from '../BaseRecord' | ||
@@ -3,0 +3,0 @@ import { createRecordType } from '../RecordType' |
import { assert } from '@tldraw/utils' | ||
import { BaseRecord, RecordId } from '../BaseRecord' | ||
import { createRecordType } from '../RecordType' | ||
import { StoreSnapshot } from '../Store' | ||
import { SerializedStore } from '../Store' | ||
import { StoreSchema } from '../StoreSchema' | ||
@@ -206,6 +206,6 @@ import { defineMigrations } from '../migrate' | ||
[StoreVersions.RemoveOrg]: { | ||
up: (store: StoreSnapshot<any>) => { | ||
up: (store: SerializedStore<any>) => { | ||
return Object.fromEntries(Object.entries(store).filter(([_, r]) => r.typeName !== 'org')) | ||
}, | ||
down: (store: StoreSnapshot<any>) => { | ||
down: (store: SerializedStore<any>) => { | ||
// noop | ||
@@ -212,0 +212,0 @@ return store |
import { BaseRecord, IdOf, RecordId } from '../BaseRecord' | ||
import { createRecordType } from '../RecordType' | ||
import { Store, StoreSnapshot } from '../Store' | ||
import { SerializedStore, Store } from '../Store' | ||
import { StoreSchema } from '../StoreSchema' | ||
@@ -93,3 +93,3 @@ | ||
describe('Validating initial data', () => { | ||
let snapshot: StoreSnapshot<Book | Author> | ||
let snapshot: SerializedStore<Book | Author> | ||
@@ -96,0 +96,0 @@ beforeEach(() => { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
580748
10072
+ Added@tldraw/state@2.0.0-canary.fc36d5b57759(transitive)
+ Added@tldraw/utils@2.0.0-canary.fc36d5b57759(transitive)
+ Addednanoid@3.3.8(transitive)
- Removed@tldraw/state@2.0.0-canary.faecd88220a7(transitive)
- Removed@tldraw/utils@2.0.0-canary.faecd88220a7(transitive)
- Removednanoid@4.0.2(transitive)
Updatednanoid@^3.3.6