2023-06-20 13:31:26 +00:00
|
|
|
import { Computed, react, RESET_VALUE, transact } from '@tldraw/state'
|
2023-06-03 20:46:53 +00:00
|
|
|
import { BaseRecord, RecordId } from '../BaseRecord'
|
2024-04-16 11:13:54 +00:00
|
|
|
import { createMigrationSequence } from '../migrate'
|
2023-04-25 11:01:25 +00:00
|
|
|
import { createRecordType } from '../RecordType'
|
|
|
|
import { CollectionDiff, RecordsDiff, Store } from '../Store'
|
|
|
|
import { StoreSchema } from '../StoreSchema'
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
interface Book extends BaseRecord<'book', RecordId<Book>> {
|
2023-04-25 11:01:25 +00:00
|
|
|
title: string
|
2023-06-03 20:46:53 +00:00
|
|
|
author: RecordId<Author>
|
2023-04-25 11:01:25 +00:00
|
|
|
numPages: number
|
|
|
|
}
|
|
|
|
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
const Book = createRecordType<Book>('book', {
|
|
|
|
validator: { validate: (book) => book as Book },
|
|
|
|
scope: 'document',
|
|
|
|
})
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
interface Author extends BaseRecord<'author', RecordId<Author>> {
|
2023-04-25 11:01:25 +00:00
|
|
|
name: string
|
|
|
|
isPseudonym: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
const Author = createRecordType<Author>('author', {
|
|
|
|
validator: { validate: (author) => author as Author },
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
scope: 'document',
|
2023-04-25 11:01:25 +00:00
|
|
|
}).withDefaultProperties(() => ({
|
|
|
|
isPseudonym: false,
|
|
|
|
}))
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
interface Visit extends BaseRecord<'visit', RecordId<Visit>> {
|
|
|
|
visitorName: string
|
|
|
|
booksInBasket: RecordId<Book>[]
|
|
|
|
}
|
|
|
|
|
|
|
|
const Visit = createRecordType<Visit>('visit', {
|
|
|
|
validator: { validate: (visit) => visit as Visit },
|
|
|
|
scope: 'session',
|
|
|
|
}).withDefaultProperties(() => ({
|
|
|
|
visitorName: 'Anonymous',
|
|
|
|
booksInBasket: [],
|
|
|
|
}))
|
|
|
|
|
|
|
|
type LibraryType = Book | Author | Visit
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
describe('Store', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
let store: Store<Book | Author | Visit>
|
2023-04-25 11:01:25 +00:00
|
|
|
beforeEach(() => {
|
|
|
|
store = new Store({
|
|
|
|
props: {},
|
2024-04-16 11:13:54 +00:00
|
|
|
schema: StoreSchema.create<LibraryType>({
|
|
|
|
book: Book,
|
|
|
|
author: Author,
|
|
|
|
visit: Visit,
|
|
|
|
}),
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows records to be added', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-11-13 11:51:22 +00:00
|
|
|
expect(store.query.records('author').get()).toEqual([
|
2023-04-25 11:01:25 +00:00
|
|
|
{ id: 'author:tolkein', typeName: 'author', name: 'J.R.R Tolkein', isPseudonym: false },
|
|
|
|
])
|
|
|
|
|
|
|
|
store.put([
|
|
|
|
{
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Book.createId('the-hobbit'),
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: 'book',
|
|
|
|
title: 'The Hobbit',
|
|
|
|
numPages: 423,
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
author: Author.createId('tolkein'),
|
2023-04-25 11:01:25 +00:00
|
|
|
},
|
|
|
|
])
|
|
|
|
|
2023-11-13 11:51:22 +00:00
|
|
|
expect(store.query.records('book').get()).toEqual([
|
2023-04-25 11:01:25 +00:00
|
|
|
{
|
|
|
|
id: 'book:the-hobbit',
|
|
|
|
typeName: 'book',
|
|
|
|
title: 'The Hobbit',
|
|
|
|
numPages: 423,
|
|
|
|
author: 'author:tolkein',
|
|
|
|
},
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with history', () => {
|
|
|
|
let authorHistory: Computed<number, RecordsDiff<Author>>
|
|
|
|
let lastDiff: RecordsDiff<Author>[] | typeof RESET_VALUE = 'undefined' as any
|
|
|
|
beforeEach(() => {
|
|
|
|
authorHistory = store.query.filterHistory('author')
|
|
|
|
react('', (lastReactedEpoch) => {
|
|
|
|
lastDiff = authorHistory.getDiffSince(lastReactedEpoch)
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(lastDiff!).toBe(RESET_VALUE)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows listening to the change history', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(lastDiff!).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
"added": {
|
|
|
|
"author:tolkein": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.R.R Tolkein",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
2023-04-25 11:01:25 +00:00
|
|
|
},
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.update(Author.createId('tolkein'), (r) => ({ ...r, name: 'Jimmy Tolks' }))
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(lastDiff!).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
"added": {},
|
|
|
|
"removed": {},
|
|
|
|
"updated": {
|
|
|
|
"author:tolkein": [
|
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.R.R Tolkein",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Jimmy Tolks",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.remove([Author.createId('tolkein')])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(lastDiff!).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
"added": {},
|
|
|
|
"removed": {
|
|
|
|
"author:tolkein": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Jimmy Tolks",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"updated": {},
|
2023-04-25 11:01:25 +00:00
|
|
|
},
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
|
|
|
|
transact(() => {
|
|
|
|
store.put([
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') }),
|
|
|
|
Author.create({ name: 'David Foster Wallace', id: Author.createId('dfw') }),
|
|
|
|
Author.create({ name: 'Cynan Jones', id: Author.createId('cj') }),
|
2023-04-25 11:01:25 +00:00
|
|
|
])
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.update(Author.createId('tolkein'), (r) => ({ ...r, name: 'Jimmy Tolks' }))
|
|
|
|
store.update(Author.createId('cj'), (r) => ({ ...r, name: 'Carter, Jimmy' }))
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
expect(lastDiff!).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
"added": {
|
|
|
|
"author:cj": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:cj",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Carter, Jimmy",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"author:dfw": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:dfw",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "David Foster Wallace",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"author:tolkein": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Jimmy Tolks",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
2023-04-25 11:01:25 +00:00
|
|
|
},
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows adding onAfterChange callbacks that see the final state of the world', () => {
|
|
|
|
/* ADDING */
|
|
|
|
store.onAfterCreate = jest.fn((current) => {
|
|
|
|
expect(current).toEqual(
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })
|
2023-04-25 11:01:25 +00:00
|
|
|
)
|
2023-11-13 11:51:22 +00:00
|
|
|
expect([...store.query.ids('author').get()]).toEqual([Author.createId('tolkein')])
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(store.onAfterCreate).toHaveBeenCalledTimes(1)
|
|
|
|
|
|
|
|
/* UPDATING */
|
|
|
|
store.onAfterChange = jest.fn((prev, current) => {
|
|
|
|
if (prev.typeName === 'author' && current.typeName === 'author') {
|
|
|
|
expect(prev.name).toBe('J.R.R Tolkein')
|
|
|
|
expect(current.name).toBe('Butch Cassidy')
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
expect(store.get(Author.createId('tolkein'))!.name).toBe('Butch Cassidy')
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.update(Author.createId('tolkein'), (r) => ({ ...r, name: 'Butch Cassidy' }))
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(store.onAfterChange).toHaveBeenCalledTimes(1)
|
|
|
|
|
|
|
|
/* REMOVING */
|
|
|
|
store.onAfterDelete = jest.fn((prev) => {
|
|
|
|
if (prev.typeName === 'author') {
|
|
|
|
expect(prev.name).toBe('Butch Cassidy')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.remove([Author.createId('tolkein')])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(store.onAfterDelete).toHaveBeenCalledTimes(1)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows finding and filtering records with a predicate', () => {
|
|
|
|
store.put([
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') }),
|
|
|
|
Author.create({ name: 'James McAvoy', id: Author.createId('mcavoy') }),
|
|
|
|
Author.create({ name: 'Butch Cassidy', id: Author.createId('cassidy') }),
|
|
|
|
Author.create({ name: 'Cynan Jones', id: Author.createId('cj') }),
|
|
|
|
Author.create({ name: 'David Foster Wallace', id: Author.createId('dfw') }),
|
2023-04-25 11:01:25 +00:00
|
|
|
])
|
2023-11-13 11:51:22 +00:00
|
|
|
const Js = store.query
|
|
|
|
.records('author')
|
|
|
|
.get()
|
|
|
|
.filter((r) => r.name.startsWith('J'))
|
2023-04-25 11:01:25 +00:00
|
|
|
expect(Js.map((j) => j.name).sort()).toEqual(['J.R.R Tolkein', 'James McAvoy'])
|
|
|
|
|
2023-11-13 11:51:22 +00:00
|
|
|
const david = store.query
|
|
|
|
.records('author')
|
|
|
|
.get()
|
|
|
|
.find((r) => r.name.startsWith('David'))
|
2023-04-25 11:01:25 +00:00
|
|
|
expect(david?.name).toBe('David Foster Wallace')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows keeping track of the ids of a particular type', () => {
|
2023-06-03 20:46:53 +00:00
|
|
|
let lastIdDiff: CollectionDiff<RecordId<Author>>[] | RESET_VALUE = []
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
const authorIds = store.query.ids('author')
|
|
|
|
|
|
|
|
react('', (lastReactedEpoch) => {
|
|
|
|
lastIdDiff = authorIds.getDiffSince(lastReactedEpoch)
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(lastIdDiff).toBe(RESET_VALUE)
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
expect(lastIdDiff).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
[
|
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"added": Set {
|
|
|
|
"author:tolkein",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
|
|
|
|
transact(() => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'James McAvoy', id: Author.createId('mcavoy') })])
|
|
|
|
store.put([Author.create({ name: 'Butch Cassidy', id: Author.createId('cassidy') })])
|
|
|
|
store.remove([Author.createId('tolkein')])
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
expect(lastIdDiff).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
[
|
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"added": Set {
|
|
|
|
"author:mcavoy",
|
|
|
|
"author:cassidy",
|
|
|
|
},
|
|
|
|
"removed": Set {
|
|
|
|
"author:tolkein",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('supports listening for changes to the whole store', async () => {
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener)
|
|
|
|
|
|
|
|
transact(() => {
|
|
|
|
store.put([
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') }),
|
|
|
|
Author.create({ name: 'James McAvoy', id: Author.createId('mcavoy') }),
|
|
|
|
Author.create({ name: 'Butch Cassidy', id: Author.createId('cassidy') }),
|
2023-04-25 11:01:25 +00:00
|
|
|
Book.create({
|
|
|
|
title: 'The Hobbit',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Book.createId('hobbit'),
|
|
|
|
author: Author.createId('tolkein'),
|
2023-04-25 11:01:25 +00:00
|
|
|
numPages: 300,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
store.put([
|
|
|
|
Book.create({
|
|
|
|
title: 'The Lord of the Rings',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Book.createId('lotr'),
|
|
|
|
author: Author.createId('tolkein'),
|
2023-04-25 11:01:25 +00:00
|
|
|
numPages: 1000,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
|
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
|
|
expect(listener.mock.lastCall[0]).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"changes": {
|
|
|
|
"added": {
|
|
|
|
"author:cassidy": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:cassidy",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Butch Cassidy",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"author:mcavoy": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:mcavoy",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "James McAvoy",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"author:tolkein": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.R.R Tolkein",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"book:hobbit": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"author": "author:tolkein",
|
|
|
|
"id": "book:hobbit",
|
|
|
|
"numPages": 300,
|
|
|
|
"title": "The Hobbit",
|
|
|
|
"typeName": "book",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"book:lotr": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"author": "author:tolkein",
|
|
|
|
"id": "book:lotr",
|
|
|
|
"numPages": 1000,
|
|
|
|
"title": "The Lord of the Rings",
|
|
|
|
"typeName": "book",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
2023-04-25 11:01:25 +00:00
|
|
|
},
|
|
|
|
"source": "user",
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
transact(() => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.update(Author.createId('tolkein'), (author) => ({
|
2023-04-25 11:01:25 +00:00
|
|
|
...author,
|
|
|
|
name: 'Jimmy Tolks',
|
|
|
|
}))
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.update(Book.createId('lotr'), (book) => ({ ...book, numPages: 42 }))
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
|
|
expect(listener).toHaveBeenCalledTimes(2)
|
|
|
|
|
|
|
|
expect(listener.mock.lastCall[0]).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"changes": {
|
|
|
|
"added": {},
|
|
|
|
"removed": {},
|
|
|
|
"updated": {
|
|
|
|
"author:tolkein": [
|
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.R.R Tolkein",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:tolkein",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Jimmy Tolks",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
],
|
2024-01-31 16:53:40 +00:00
|
|
|
"book:lotr": [
|
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"author": "author:tolkein",
|
|
|
|
"id": "book:lotr",
|
|
|
|
"numPages": 1000,
|
|
|
|
"title": "The Lord of the Rings",
|
|
|
|
"typeName": "book",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"author": "author:tolkein",
|
|
|
|
"id": "book:lotr",
|
|
|
|
"numPages": 42,
|
|
|
|
"title": "The Lord of the Rings",
|
|
|
|
"typeName": "book",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"source": "user",
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
transact(() => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.update(Author.createId('mcavoy'), (author) => ({
|
2023-04-25 11:01:25 +00:00
|
|
|
...author,
|
|
|
|
name: 'Sookie Houseboat',
|
|
|
|
}))
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.remove([Book.createId('lotr')])
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
|
|
expect(listener).toHaveBeenCalledTimes(3)
|
|
|
|
|
|
|
|
expect(listener.mock.lastCall[0]).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"changes": {
|
|
|
|
"added": {},
|
|
|
|
"removed": {
|
|
|
|
"book:lotr": {
|
2023-04-25 11:01:25 +00:00
|
|
|
"author": "author:tolkein",
|
|
|
|
"id": "book:lotr",
|
|
|
|
"numPages": 42,
|
|
|
|
"title": "The Lord of the Rings",
|
|
|
|
"typeName": "book",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"updated": {
|
|
|
|
"author:mcavoy": [
|
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:mcavoy",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "James McAvoy",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
2023-04-25 11:01:25 +00:00
|
|
|
"id": "author:mcavoy",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "Sookie Houseboat",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"source": "user",
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
it('supports filtering history by scope', () => {
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener, {
|
|
|
|
scope: 'session',
|
|
|
|
})
|
|
|
|
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.R.R Tolkien', id: Author.createId('tolkien') }),
|
|
|
|
Book.create({
|
|
|
|
title: 'The Hobbit',
|
|
|
|
id: Book.createId('hobbit'),
|
|
|
|
author: Author.createId('tolkien'),
|
|
|
|
numPages: 300,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(0)
|
|
|
|
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.D. Salinger', id: Author.createId('salinger') }),
|
|
|
|
Visit.create({ id: Visit.createId('jimmy'), visitorName: 'Jimmy Beans' }),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
|
|
|
|
|
|
expect(listener.mock.calls[0][0].changes).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"added": {
|
|
|
|
"visit:jimmy": {
|
|
|
|
"booksInBasket": [],
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
"id": "visit:jimmy",
|
|
|
|
"typeName": "visit",
|
|
|
|
"visitorName": "Jimmy Beans",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
}
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('supports filtering history by scope (2)', () => {
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener, {
|
|
|
|
scope: 'document',
|
|
|
|
})
|
|
|
|
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.D. Salinger', id: Author.createId('salinger') }),
|
|
|
|
Visit.create({ id: Visit.createId('jimmy'), visitorName: 'Jimmy Beans' }),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
|
|
|
|
|
|
expect(listener.mock.calls[0][0].changes).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"added": {
|
|
|
|
"author:salinger": {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
"id": "author:salinger",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.D. Salinger",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
}
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('supports filtering history by source', () => {
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener, {
|
|
|
|
source: 'remote',
|
|
|
|
})
|
|
|
|
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.D. Salinger', id: Author.createId('salinger') }),
|
|
|
|
Visit.create({ id: Visit.createId('jimmy'), visitorName: 'Jimmy Beans' }),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(0)
|
|
|
|
|
|
|
|
store.mergeRemoteChanges(() => {
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.R.R Tolkien', id: Author.createId('tolkien') }),
|
|
|
|
Book.create({
|
|
|
|
title: 'The Hobbit',
|
|
|
|
id: Book.createId('hobbit'),
|
|
|
|
author: Author.createId('tolkien'),
|
|
|
|
numPages: 300,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
|
|
|
|
|
|
expect(listener.mock.calls[0][0].changes).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"added": {
|
|
|
|
"author:tolkien": {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
"id": "author:tolkien",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.R.R Tolkien",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"book:hobbit": {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
"author": "author:tolkien",
|
|
|
|
"id": "book:hobbit",
|
|
|
|
"numPages": 300,
|
|
|
|
"title": "The Hobbit",
|
|
|
|
"typeName": "book",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
}
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('supports filtering history by source (user)', () => {
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener, {
|
|
|
|
source: 'user',
|
|
|
|
})
|
|
|
|
|
|
|
|
store.mergeRemoteChanges(() => {
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.R.R Tolkien', id: Author.createId('tolkien') }),
|
|
|
|
Book.create({
|
|
|
|
title: 'The Hobbit',
|
|
|
|
id: Book.createId('hobbit'),
|
|
|
|
author: Author.createId('tolkien'),
|
|
|
|
numPages: 300,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(0)
|
|
|
|
|
|
|
|
store.put([
|
|
|
|
Author.create({ name: 'J.D. Salinger', id: Author.createId('salinger') }),
|
|
|
|
Visit.create({ id: Visit.createId('jimmy'), visitorName: 'Jimmy Beans' }),
|
|
|
|
])
|
|
|
|
|
|
|
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
|
|
|
|
|
|
expect(listener.mock.calls[0][0].changes).toMatchInlineSnapshot(`
|
2024-01-31 16:53:40 +00:00
|
|
|
{
|
|
|
|
"added": {
|
|
|
|
"author:salinger": {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
"id": "author:salinger",
|
|
|
|
"isPseudonym": false,
|
|
|
|
"name": "J.D. Salinger",
|
|
|
|
"typeName": "author",
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"visit:jimmy": {
|
|
|
|
"booksInBasket": [],
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
"id": "visit:jimmy",
|
|
|
|
"typeName": "visit",
|
|
|
|
"visitorName": "Jimmy Beans",
|
|
|
|
},
|
|
|
|
},
|
2024-01-31 16:53:40 +00:00
|
|
|
"removed": {},
|
|
|
|
"updated": {},
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
}
|
|
|
|
`)
|
|
|
|
})
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
it('does not keep global history if no listeners are attached', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
expect((store as any).historyAccumulator._history).toHaveLength(0)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('flushes history before attaching listeners', async () => {
|
2023-05-12 09:43:51 +00:00
|
|
|
try {
|
|
|
|
// @ts-expect-error
|
|
|
|
globalThis.__FORCE_RAF_IN_TESTS__ = true
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-05-12 09:43:51 +00:00
|
|
|
const firstListener = jest.fn()
|
|
|
|
store.listen(firstListener)
|
|
|
|
expect(firstListener).toHaveBeenCalledTimes(0)
|
2023-04-25 11:01:25 +00:00
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'Chips McCoy', id: Author.createId('chips') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-12 09:43:51 +00:00
|
|
|
expect(firstListener).toHaveBeenCalledTimes(0)
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-12 09:43:51 +00:00
|
|
|
const secondListener = jest.fn()
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-12 09:43:51 +00:00
|
|
|
store.listen(secondListener)
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-12 09:43:51 +00:00
|
|
|
expect(firstListener).toHaveBeenCalledTimes(1)
|
|
|
|
expect(secondListener).toHaveBeenCalledTimes(0)
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-12 09:43:51 +00:00
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-12 09:43:51 +00:00
|
|
|
expect(firstListener).toHaveBeenCalledTimes(1)
|
|
|
|
expect(secondListener).toHaveBeenCalledTimes(0)
|
|
|
|
} finally {
|
|
|
|
// @ts-expect-error
|
|
|
|
globalThis.__FORCE_RAF_IN_TESTS__ = false
|
|
|
|
}
|
2023-04-25 11:01:25 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('does not overwrite default properties with undefined', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
const tolkein = Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })
|
2023-04-25 11:01:25 +00:00
|
|
|
expect(tolkein.isPseudonym).toBe(false)
|
|
|
|
|
|
|
|
const harkaway = Author.create({
|
|
|
|
name: 'Nick Harkaway',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Author.createId('harkaway'),
|
2023-04-25 11:01:25 +00:00
|
|
|
isPseudonym: true,
|
|
|
|
})
|
|
|
|
expect(harkaway.isPseudonym).toBe(true)
|
|
|
|
|
|
|
|
const burns = Author.create({
|
|
|
|
name: 'Anna Burns',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Author.createId('burns'),
|
2023-04-25 11:01:25 +00:00
|
|
|
isPseudonym: undefined,
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(burns.isPseudonym).toBe(false)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('allows changed to be merged without triggering listeners', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
const id = Author.createId('tolkein')
|
2023-04-25 11:01:25 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id })])
|
|
|
|
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener)
|
|
|
|
|
|
|
|
// Return the exact same value that came in
|
|
|
|
store.update(id, (author) => author)
|
|
|
|
|
|
|
|
expect(listener).not.toHaveBeenCalled()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('tells listeners the source of the changes so they can decide if they want to run or not', async () => {
|
|
|
|
const listener = jest.fn()
|
|
|
|
store.listen(listener)
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'Jimmy Beans', id: Author.createId('jimmy') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
|
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
|
|
expect(listener.mock.calls[0][0].source).toBe('user')
|
|
|
|
|
|
|
|
store.mergeRemoteChanges(() => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
store.put([
|
|
|
|
Book.create({
|
|
|
|
title: 'The Hobbit',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Book.createId('hobbit'),
|
|
|
|
author: Author.createId('tolkein'),
|
2023-04-25 11:01:25 +00:00
|
|
|
numPages: 300,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
|
|
expect(listener).toHaveBeenCalledTimes(2)
|
|
|
|
expect(listener.mock.calls[1][0].source).toBe('remote')
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
store.put([Author.create({ name: 'Steve Ok', id: Author.createId('stever') })])
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
|
|
expect(listener).toHaveBeenCalledTimes(3)
|
|
|
|
expect(listener.mock.calls[2][0].source).toBe('user')
|
|
|
|
})
|
|
|
|
})
|
2023-05-30 15:22:49 +00:00
|
|
|
|
|
|
|
describe('snapshots', () => {
|
|
|
|
let store: Store<Book | Author>
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
store = new Store({
|
|
|
|
props: {},
|
2024-04-16 11:13:54 +00:00
|
|
|
schema: StoreSchema.create<Book | Author>({
|
|
|
|
book: Book,
|
|
|
|
author: Author,
|
|
|
|
}),
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
transact(() => {
|
|
|
|
store.put([
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
Author.create({ name: 'J.R.R Tolkein', id: Author.createId('tolkein') }),
|
|
|
|
Author.create({ name: 'James McAvoy', id: Author.createId('mcavoy') }),
|
|
|
|
Author.create({ name: 'Butch Cassidy', id: Author.createId('cassidy') }),
|
2023-05-30 15:22:49 +00:00
|
|
|
Book.create({
|
|
|
|
title: 'The Hobbit',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Book.createId('hobbit'),
|
|
|
|
author: Author.createId('tolkein'),
|
2023-05-30 15:22:49 +00:00
|
|
|
numPages: 300,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
store.put([
|
|
|
|
Book.create({
|
|
|
|
title: 'The Lord of the Rings',
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
id: Book.createId('lotr'),
|
|
|
|
author: Author.createId('tolkein'),
|
2023-05-30 15:22:49 +00:00
|
|
|
numPages: 1000,
|
|
|
|
}),
|
|
|
|
])
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('creates and loads a snapshot', () => {
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
const serializedStore1 = store.serialize('all')
|
2023-05-30 15:22:49 +00:00
|
|
|
const serializedSchema1 = store.schema.serialize()
|
|
|
|
|
|
|
|
const snapshot1 = store.getSnapshot()
|
|
|
|
|
|
|
|
const store2 = new Store({
|
|
|
|
props: {},
|
2024-04-16 11:13:54 +00:00
|
|
|
schema: StoreSchema.create<Book | Author>({
|
|
|
|
book: Book,
|
|
|
|
author: Author,
|
|
|
|
}),
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
store2.loadSnapshot(snapshot1)
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
const serializedStore2 = store2.serialize('all')
|
2023-05-30 15:22:49 +00:00
|
|
|
const serializedSchema2 = store2.schema.serialize()
|
|
|
|
const snapshot2 = store2.getSnapshot()
|
|
|
|
|
|
|
|
expect(serializedStore1).toEqual(serializedStore2)
|
|
|
|
expect(serializedSchema1).toEqual(serializedSchema2)
|
|
|
|
expect(snapshot1).toEqual(snapshot2)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('throws errors when loading a snapshot with a different schema', () => {
|
|
|
|
const snapshot1 = store.getSnapshot()
|
|
|
|
|
|
|
|
const store2 = new Store({
|
|
|
|
props: {},
|
2024-04-16 11:13:54 +00:00
|
|
|
schema: StoreSchema.create<Book>({
|
|
|
|
book: Book,
|
|
|
|
// no author
|
|
|
|
}),
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
expect(() => {
|
|
|
|
// @ts-expect-error
|
|
|
|
store2.loadSnapshot(snapshot1)
|
2024-04-16 11:13:54 +00:00
|
|
|
}).toThrowErrorMatchingInlineSnapshot(`"Missing definition for record type author"`)
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('throws errors when loading a snapshot with a different schema', () => {
|
|
|
|
const snapshot1 = store.getSnapshot()
|
|
|
|
|
|
|
|
const store2 = new Store({
|
|
|
|
props: {},
|
2024-04-16 11:13:54 +00:00
|
|
|
schema: StoreSchema.create<Book>({
|
|
|
|
book: Book,
|
|
|
|
}),
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
expect(() => {
|
2024-04-16 11:13:54 +00:00
|
|
|
store2.loadSnapshot(snapshot1 as any)
|
|
|
|
}).toThrowErrorMatchingInlineSnapshot(`"Missing definition for record type author"`)
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('migrates the snapshot', () => {
|
|
|
|
const snapshot1 = store.getSnapshot()
|
2024-04-16 11:13:54 +00:00
|
|
|
const up = jest.fn((s: any) => {
|
|
|
|
s['book:lotr'].numPages = 42
|
|
|
|
})
|
|
|
|
|
|
|
|
expect((snapshot1.store as any)['book:lotr'].numPages).toBe(1000)
|
2023-05-30 15:22:49 +00:00
|
|
|
|
|
|
|
const store2 = new Store({
|
|
|
|
props: {},
|
|
|
|
schema: StoreSchema.create<Book | Author>(
|
|
|
|
{
|
|
|
|
book: Book,
|
|
|
|
author: Author,
|
|
|
|
},
|
|
|
|
{
|
2024-04-16 11:13:54 +00:00
|
|
|
migrations: [
|
|
|
|
createMigrationSequence({
|
|
|
|
sequenceId: 'com.tldraw',
|
|
|
|
retroactive: true,
|
|
|
|
sequence: [
|
|
|
|
{
|
|
|
|
id: `com.tldraw/1`,
|
|
|
|
scope: 'store',
|
|
|
|
up,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}),
|
|
|
|
],
|
2023-05-30 15:22:49 +00:00
|
|
|
}
|
|
|
|
),
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(() => {
|
|
|
|
store2.loadSnapshot(snapshot1)
|
2024-02-04 11:19:47 +00:00
|
|
|
}).not.toThrow()
|
2024-04-16 11:13:54 +00:00
|
|
|
|
|
|
|
expect(up).toHaveBeenCalledTimes(1)
|
|
|
|
expect(store2.get(Book.createId('lotr'))!.numPages).toBe(42)
|
2023-05-30 15:22:49 +00:00
|
|
|
})
|
|
|
|
})
|