[DX] sensible defaults for createTLStore (#3886)

`createTLStore` had defaults of empty arrays for shapeUtils and
bindingUtils. this is problematic since people who already are calling
`createTLStore` manually with like `createTLStore({shapeUtils:
defaultShapeUtils})` will miss out on bindings utils when they upgrade
to the latest version, and this will probably only fail at runtime for
them.

To prevent issues we could have made `shapeUtils` and `bindingUtils`
required args but it feels better to me, long term, if we bring
`createTLStore` in line with `createTLSchema` and configure it to use
tldraw's default shapes/bindings if no custom overrides are specified.

i.e. we can do this

```diff
- const store = createTLStore({ shapeUtils: defaultShapeUtils, bindingUtils: defaultBindingUtils })
+ const store = createTLStore()
```

There's still technically potential for breaking changes by people
accidentally including the arrow binding util when they might not have
arrows in the app, but I don't think that's likely to actually cause any
bugs unless they add their own arrow binding type later on.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Add a step-by-step description of how to test your PR here.
2.

- [ ] Unit Tests
- [ ] End to end tests

### Release Notes

- Add a brief release note for your PR here.
This commit is contained in:
David Sheldrick 2024-06-05 15:29:54 +01:00 committed by GitHub
parent 5d58924f74
commit 5d7f368fd6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 20 additions and 41 deletions

View file

@ -130,10 +130,7 @@ The `store` property of the `<Tldraw>` / `<TldrawEditor>` components accepts a s
export default function () {
const [store] = useState(() => {
// Create the store
const newStore = createTLStore({
shapeUtils: defaultShapeUtils,
bindingUtils: defaultBindingUtils,
})
const newStore = createTLStore()
// Get the snapshot
const stringified = localStorage.getItem('my-editor-snapshot')
@ -165,10 +162,7 @@ export default function () {
if (cancelled) return
// Create the store
const newStore = createTLStore({
shapeUtils: defaultShapeUtils,
bindingUtils: defaultBindingUtils,
})
const newStore = createTLStore()
// Load the snapshot
loadSnapshot(newStore, snapshot)

View file

@ -1,13 +1,5 @@
import { useLayoutEffect, useState } from 'react'
import {
Tldraw,
createTLStore,
defaultBindingUtils,
defaultShapeUtils,
getSnapshot,
loadSnapshot,
throttle,
} from 'tldraw'
import { Tldraw, createTLStore, getSnapshot, loadSnapshot, throttle } from 'tldraw'
import 'tldraw/tldraw.css'
// There's a guide at the bottom of this file!
@ -16,9 +8,7 @@ const PERSISTENCE_KEY = 'example-3'
export default function PersistenceExample() {
//[1]
const [store] = useState(() =>
createTLStore({ shapeUtils: defaultShapeUtils, bindingUtils: defaultBindingUtils })
)
const [store] = useState(() => createTLStore())
//[2]
const [loadingState, setLoadingState] = useState<
{ status: 'loading' } | { status: 'ready' } | { status: 'error'; error: string }

View file

@ -1,22 +1,16 @@
import { TldrawFile, createTLStore, defaultBindingUtils, defaultShapeUtils } from 'tldraw'
import { TldrawFile, createTLSchema } from 'tldraw'
import * as vscode from 'vscode'
import { nicelog } from './utils'
export const defaultFileContents: TldrawFile = {
tldrawFileFormatVersion: 1,
schema: createTLStore({
shapeUtils: defaultShapeUtils,
bindingUtils: defaultBindingUtils,
}).schema.serialize(),
schema: createTLSchema().serialize(),
records: [],
}
export const fileContentWithErrors: TldrawFile = {
tldrawFileFormatVersion: 1,
schema: createTLStore({
shapeUtils: defaultShapeUtils,
bindingUtils: defaultBindingUtils,
}).schema.serialize(),
schema: createTLSchema().serialize(),
records: [{ typeName: 'shape', id: null } as any],
}

View file

@ -458,7 +458,7 @@ export function counterClockwiseAngleDist(a0: number, a1: number): number;
export function createSessionStateSnapshotSignal(store: TLStore): Signal<null | TLSessionStateSnapshot>;
// @public
export function createTLStore({ initialData, defaultName, id, ...rest }: TLStoreOptions): TLStore;
export function createTLStore({ initialData, defaultName, id, ...rest }?: TLStoreOptions): TLStore;
// @public (undocumented)
export function createTLUser(opts?: {

View file

@ -31,20 +31,22 @@ export function createTLStore({
defaultName = '',
id,
...rest
}: TLStoreOptions): TLStore {
}: TLStoreOptions = {}): TLStore {
const schema =
'schema' in rest && rest.schema
? // we have a schema
rest.schema
: // we need a schema
createTLSchema({
shapes: utilsToMap(
checkShapesAndAddCore('shapeUtils' in rest && rest.shapeUtils ? rest.shapeUtils : [])
),
bindings: utilsToMap(
checkBindings('bindingUtils' in rest && rest.bindingUtils ? rest.bindingUtils : [])
),
migrations: 'migrations' in rest ? rest.migrations : [],
shapes:
'shapeUtils' in rest && rest.shapeUtils
? utilsToMap(checkShapesAndAddCore(rest.shapeUtils))
: undefined,
bindings:
'bindingUtils' in rest && rest.bindingUtils
? utilsToMap(checkBindings(rest.bindingUtils))
: undefined,
migrations: 'migrations' in rest ? rest.migrations : undefined,
})
return new Store({

View file

@ -5,8 +5,7 @@ import {
TLDocument,
TLRecord,
ZERO_INDEX_KEY,
createTLStore,
defaultShapeUtils,
createTLSchema,
} from 'tldraw'
import { type WebSocket } from 'ws'
import { RoomSessionState } from '../lib/RoomSession'
@ -95,7 +94,7 @@ class TLServerTestImpl extends TLServer {
}
type UnpackPromise<T> = T extends Promise<infer U> ? U : T
const schema = createTLStore({ shapeUtils: defaultShapeUtils }).schema.serialize()
const schema = createTLSchema().serialize()
let server: TLServerTestImpl
let sockets: UnpackPromise<ReturnType<typeof server.createSocketPair>>