UNPKG

@tldraw/tlschema

Version:

A tiny little drawing app (schema).

160 lines (159 loc) 5.51 kB
import { annotateError, structuredClone } from "@tldraw/utils"; import { CameraRecordType } from "./records/TLCamera.mjs"; import { DocumentRecordType, TLDOCUMENT_ID } from "./records/TLDocument.mjs"; import { TLINSTANCE_ID } from "./records/TLInstance.mjs"; import { PageRecordType } from "./records/TLPage.mjs"; import { InstancePageStateRecordType } from "./records/TLPageState.mjs"; import { PointerRecordType, TLPOINTER_ID } from "./records/TLPointer.mjs"; function sortByIndex(a, b) { if (a.index < b.index) { return -1; } else if (a.index > b.index) { return 1; } return 0; } function redactRecordForErrorReporting(record) { if (record.typeName === "asset") { if ("src" in record) { record.src = "<redacted>"; } if ("src" in record.props) { record.props.src = "<redacted>"; } } } function onValidationFailure({ error, phase, record, recordBefore }) { const isExistingValidationIssue = ( // if we're initializing the store for the first time, we should // allow invalid records so people can load old buggy data: (phase === "initialize") ); annotateError(error, { tags: { origin: "store.validateRecord", storePhase: phase, isExistingValidationIssue }, extras: { recordBefore: recordBefore ? redactRecordForErrorReporting(structuredClone(recordBefore)) : void 0, recordAfter: redactRecordForErrorReporting(structuredClone(record)) } }); throw error; } function getDefaultPages() { return [ PageRecordType.create({ id: "page:page", name: "Page 1", index: "a1", meta: {} }) ]; } function createIntegrityChecker(store) { const $pageIds = store.query.ids("page"); const $pageStates = store.query.records("instance_page_state"); const ensureStoreIsUsable = () => { if (!store.has(TLDOCUMENT_ID)) { store.put([DocumentRecordType.create({ id: TLDOCUMENT_ID, name: store.props.defaultName })]); return ensureStoreIsUsable(); } if (!store.has(TLPOINTER_ID)) { store.put([PointerRecordType.create({ id: TLPOINTER_ID })]); return ensureStoreIsUsable(); } const pageIds = $pageIds.get(); if (pageIds.size === 0) { store.put(getDefaultPages()); return ensureStoreIsUsable(); } const getFirstPageId = () => [...pageIds].map((id) => store.get(id)).sort(sortByIndex)[0].id; const instanceState = store.get(TLINSTANCE_ID); if (!instanceState) { store.put([ store.schema.types.instance.create({ id: TLINSTANCE_ID, currentPageId: getFirstPageId(), exportBackground: true }) ]); return ensureStoreIsUsable(); } else if (!pageIds.has(instanceState.currentPageId)) { store.put([{ ...instanceState, currentPageId: getFirstPageId() }]); return ensureStoreIsUsable(); } const missingPageStateIds = /* @__PURE__ */ new Set(); const missingCameraIds = /* @__PURE__ */ new Set(); for (const id of pageIds) { const pageStateId = InstancePageStateRecordType.createId(id); const pageState = store.get(pageStateId); if (!pageState) { missingPageStateIds.add(pageStateId); } const cameraId = CameraRecordType.createId(id); if (!store.has(cameraId)) { missingCameraIds.add(cameraId); } } if (missingPageStateIds.size > 0) { store.put( [...missingPageStateIds].map( (id) => InstancePageStateRecordType.create({ id, pageId: InstancePageStateRecordType.parseId(id) }) ) ); } if (missingCameraIds.size > 0) { store.put([...missingCameraIds].map((id) => CameraRecordType.create({ id }))); } const pageStates = $pageStates.get(); for (const pageState of pageStates) { if (!pageIds.has(pageState.pageId)) { store.remove([pageState.id]); continue; } if (pageState.croppingShapeId && !store.has(pageState.croppingShapeId)) { store.put([{ ...pageState, croppingShapeId: null }]); return ensureStoreIsUsable(); } if (pageState.focusedGroupId && !store.has(pageState.focusedGroupId)) { store.put([{ ...pageState, focusedGroupId: null }]); return ensureStoreIsUsable(); } if (pageState.hoveredShapeId && !store.has(pageState.hoveredShapeId)) { store.put([{ ...pageState, hoveredShapeId: null }]); return ensureStoreIsUsable(); } const filteredSelectedIds = pageState.selectedShapeIds.filter((id) => store.has(id)); if (filteredSelectedIds.length !== pageState.selectedShapeIds.length) { store.put([{ ...pageState, selectedShapeIds: filteredSelectedIds }]); return ensureStoreIsUsable(); } const filteredHintingIds = pageState.hintingShapeIds.filter((id) => store.has(id)); if (filteredHintingIds.length !== pageState.hintingShapeIds.length) { store.put([{ ...pageState, hintingShapeIds: filteredHintingIds }]); return ensureStoreIsUsable(); } const filteredErasingIds = pageState.erasingShapeIds.filter((id) => store.has(id)); if (filteredErasingIds.length !== pageState.erasingShapeIds.length) { store.put([{ ...pageState, erasingShapeIds: filteredErasingIds }]); return ensureStoreIsUsable(); } } }; return ensureStoreIsUsable; } export { createIntegrityChecker, onValidationFailure }; //# sourceMappingURL=TLStore.mjs.map