@tldraw/sync-core 5.4.0-next.ef99ab47e5ce → 5.5.0-next.6d9e51e9f3f7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +17 -13
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/NodeSqliteWrapper.js +1 -1
- package/dist-cjs/lib/NodeSqliteWrapper.js.map +2 -2
- package/dist-cjs/lib/TLSyncClient.js +20 -1
- package/dist-cjs/lib/TLSyncClient.js.map +2 -2
- package/dist-cjs/lib/TLSyncStorage.js +1 -1
- package/dist-cjs/lib/TLSyncStorage.js.map +2 -2
- package/dist-esm/index.d.mts +17 -13
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/NodeSqliteWrapper.mjs +1 -1
- package/dist-esm/lib/NodeSqliteWrapper.mjs.map +2 -2
- package/dist-esm/lib/TLSyncClient.mjs +20 -1
- package/dist-esm/lib/TLSyncClient.mjs.map +2 -2
- package/dist-esm/lib/TLSyncStorage.mjs +1 -1
- package/dist-esm/lib/TLSyncStorage.mjs.map +2 -2
- package/package.json +14 -7
- package/src/lib/NodeSqliteWrapper.test.ts +29 -0
- package/src/lib/NodeSqliteWrapper.ts +4 -1
- package/src/lib/TLSyncClient.test.ts +64 -6
- package/src/lib/TLSyncClient.ts +38 -2
- package/src/lib/TLSyncStorage.test.ts +37 -0
- package/src/lib/TLSyncStorage.ts +4 -2
|
@@ -122,6 +122,43 @@ describe('loadSnapshotIntoStorage', () => {
|
|
|
122
122
|
expect(storage.getClock()).toBe(5)
|
|
123
123
|
})
|
|
124
124
|
|
|
125
|
+
it('[SL3] does not delete while a key iterator is open (better-sqlite3 rejects that)', () => {
|
|
126
|
+
const extraPage = makePage('extra', 'Extra')
|
|
127
|
+
const storage = new InMemorySyncStorage<TLRecord>({
|
|
128
|
+
snapshot: makeContractSnapshot([...contractRecords, extraPage]),
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
storage.transaction((txn) => {
|
|
132
|
+
// better-sqlite3 throws on any write while a statement iterator is still open; mimic
|
|
133
|
+
// that so a delete issued from inside `for (const id of txn.keys())` fails loudly
|
|
134
|
+
let openIterators = 0
|
|
135
|
+
const guarded: typeof txn = Object.create(txn, {
|
|
136
|
+
keys: {
|
|
137
|
+
value: function* () {
|
|
138
|
+
openIterators++
|
|
139
|
+
try {
|
|
140
|
+
yield* Array.from(txn.keys())
|
|
141
|
+
} finally {
|
|
142
|
+
openIterators--
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
delete: {
|
|
147
|
+
value: (id: string) => {
|
|
148
|
+
if (openIterators > 0) {
|
|
149
|
+
throw new Error('This database connection is busy executing a query')
|
|
150
|
+
}
|
|
151
|
+
return txn.delete(id)
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
})
|
|
155
|
+
loadSnapshotIntoStorage(guarded, contractSchema, makeContractSnapshot(contractRecords))
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
expect(storage.documents.has(extraPage.id)).toBe(false)
|
|
159
|
+
expect(storage.tombstones.has(extraPage.id)).toBe(true)
|
|
160
|
+
})
|
|
161
|
+
|
|
125
162
|
it('[SL4] persists the snapshot schema and migrates loaded records to the current version', () => {
|
|
126
163
|
interface TestRecord extends BaseRecord<'test', RecordId<TestRecord>> {
|
|
127
164
|
value: number
|
package/src/lib/TLSyncStorage.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StoreSchema, SynchronousStorage, UnknownRecord } from '@tldraw/store'
|
|
2
|
+
import { TLStoreSnapshot } from '@tldraw/tlschema'
|
|
2
3
|
import { assert, isEqual, objectMapEntriesIterable, objectMapValues } from '@tldraw/utils'
|
|
3
|
-
import { TLStoreSnapshot } from 'tldraw'
|
|
4
4
|
import { diffRecord, NetworkDiff, RecordOpType } from './diff'
|
|
5
5
|
import { RoomSnapshot } from './TLSyncRoom'
|
|
6
6
|
|
|
@@ -205,7 +205,9 @@ export function loadSnapshotIntoStorage<R extends UnknownRecord>(
|
|
|
205
205
|
if (isEqual(existing, doc.state)) continue
|
|
206
206
|
txn.set(doc.state.id, doc.state as R)
|
|
207
207
|
}
|
|
208
|
-
|
|
208
|
+
// materialize the keys first: some SQLite drivers (better-sqlite3) refuse writes while a
|
|
209
|
+
// statement iterator is open, so deleting during `keys()` would throw
|
|
210
|
+
for (const id of Array.from(txn.keys())) {
|
|
209
211
|
if (!docIds.has(id)) {
|
|
210
212
|
txn.delete(id)
|
|
211
213
|
}
|