@tldraw/store
Version:
tldraw infinite canvas SDK (store).
166 lines (165 loc) • 5.39 kB
JavaScript
import { assert, objectMapEntries } from "@tldraw/utils";
let didWarn = false;
function defineMigrations(opts) {
const { currentVersion, firstVersion, migrators = {}, subTypeKey, subTypeMigrations } = opts;
if (!didWarn) {
console.warn(
`The 'defineMigrations' function is deprecated and will be removed in a future release. Use the new migrations API instead. See the migration guide for more info: https://tldraw.dev/docs/persistence#Updating-legacy-shape-migrations-defineMigrations`
);
didWarn = true;
}
if (typeof currentVersion === "number" && typeof firstVersion === "number") {
if (currentVersion === firstVersion) {
throw Error(`Current version is equal to initial version.`);
} else if (currentVersion < firstVersion) {
throw Error(`Current version is lower than initial version.`);
}
}
return {
firstVersion: firstVersion ?? 0,
// defaults
currentVersion: currentVersion ?? 0,
// defaults
migrators,
subTypeKey,
subTypeMigrations
};
}
function squashDependsOn(sequence) {
const result = [];
for (let i = sequence.length - 1; i >= 0; i--) {
const elem = sequence[i];
if (!("id" in elem)) {
const dependsOn = elem.dependsOn;
const prev = result[0];
if (prev) {
result[0] = {
...prev,
dependsOn: dependsOn.concat(prev.dependsOn ?? [])
};
}
} else {
result.unshift(elem);
}
}
return result;
}
function createMigrationSequence({
sequence,
sequenceId,
retroactive = true
}) {
const migrations = {
sequenceId,
retroactive,
sequence: squashDependsOn(sequence)
};
validateMigrations(migrations);
return migrations;
}
function createMigrationIds(sequenceId, versions) {
return Object.fromEntries(
objectMapEntries(versions).map(([key, version]) => [key, `${sequenceId}/${version}`])
);
}
function createRecordMigrationSequence(opts) {
const sequenceId = opts.sequenceId;
return createMigrationSequence({
sequenceId,
retroactive: opts.retroactive ?? true,
sequence: opts.sequence.map(
(m) => "id" in m ? {
...m,
scope: "record",
filter: (r) => r.typeName === opts.recordType && (m.filter?.(r) ?? true) && (opts.filter?.(r) ?? true)
} : m
)
});
}
function sortMigrations(migrations) {
const byId = new Map(migrations.map((m) => [m.id, m]));
const isProcessing = /* @__PURE__ */ new Set();
const result = [];
function process(m) {
assert(!isProcessing.has(m.id), `Circular dependency in migrations: ${m.id}`);
isProcessing.add(m.id);
const { version, sequenceId } = parseMigrationId(m.id);
const parent = byId.get(`${sequenceId}/${version - 1}`);
if (parent) {
process(parent);
}
if (m.dependsOn) {
for (const dep of m.dependsOn) {
const depMigration = byId.get(dep);
if (depMigration) {
process(depMigration);
}
}
}
byId.delete(m.id);
result.push(m);
}
for (const m of byId.values()) {
process(m);
}
return result;
}
function parseMigrationId(id) {
const [sequenceId, version] = id.split("/");
return { sequenceId, version: parseInt(version) };
}
function validateMigrationId(id, expectedSequenceId) {
if (expectedSequenceId) {
assert(
id.startsWith(expectedSequenceId + "/"),
`Every migration in sequence '${expectedSequenceId}' must have an id starting with '${expectedSequenceId}/'. Got invalid id: '${id}'`
);
}
assert(id.match(/^(.*?)\/(0|[1-9]\d*)$/), `Invalid migration id: '${id}'`);
}
function validateMigrations(migrations) {
assert(
!migrations.sequenceId.includes("/"),
`sequenceId cannot contain a '/', got ${migrations.sequenceId}`
);
assert(migrations.sequenceId.length, "sequenceId must be a non-empty string");
if (migrations.sequence.length === 0) {
return;
}
validateMigrationId(migrations.sequence[0].id, migrations.sequenceId);
let n = parseMigrationId(migrations.sequence[0].id).version;
assert(
n === 1,
`Expected the first migrationId to be '${migrations.sequenceId}/1' but got '${migrations.sequence[0].id}'`
);
for (let i = 1; i < migrations.sequence.length; i++) {
const id = migrations.sequence[i].id;
validateMigrationId(id, migrations.sequenceId);
const m = parseMigrationId(id).version;
assert(
m === n + 1,
`Migration id numbers must increase in increments of 1, expected ${migrations.sequenceId}/${n + 1} but got '${migrations.sequence[i].id}'`
);
n = m;
}
}
var MigrationFailureReason = /* @__PURE__ */ ((MigrationFailureReason2) => {
MigrationFailureReason2["IncompatibleSubtype"] = "incompatible-subtype";
MigrationFailureReason2["UnknownType"] = "unknown-type";
MigrationFailureReason2["TargetVersionTooNew"] = "target-version-too-new";
MigrationFailureReason2["TargetVersionTooOld"] = "target-version-too-old";
MigrationFailureReason2["MigrationError"] = "migration-error";
MigrationFailureReason2["UnrecognizedSubtype"] = "unrecognized-subtype";
return MigrationFailureReason2;
})(MigrationFailureReason || {});
export {
MigrationFailureReason,
createMigrationIds,
createMigrationSequence,
createRecordMigrationSequence,
defineMigrations,
parseMigrationId,
sortMigrations,
validateMigrations
};
//# sourceMappingURL=migrate.mjs.map