mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
* store, properties, manifest * interfaces * init and backups * fix init and backups * file models * more versions * dependencies * config except dynamic types * clean up config * remove disabled from non-dynamic vaues * actions * standardize example code block formats * wip: actions refactor Co-authored-by: Jade <Blu-J@users.noreply.github.com> * commit types * fix types * update types * update action request type * update apis * add description to actionrequest * clean up imports * revert package json * chore: Remove the recursive to the index * chore: Remove the other thing I was testing * flatten action requests * update container runtime with new config paradigm * new actions strategy * seems to be working * misc backend fixes * fix fe bugs * only show breakages if breakages * only show success modal if result * don't panic on failed removal * hide config from actions page * polyfill autoconfig * use metadata strategy for actions instead of prev * misc fixes * chore: split the sdk into 2 libs (#2736) * follow sideload progress (#2718) * follow sideload progress * small bugfix * shareReplay with no refcount false * don't wrap sideload progress in RPCResult * dont present toast --------- Co-authored-by: Aiden McClelland <me@drbonez.dev> * chore: Add the initial of the creation of the two sdk * chore: Add in the baseDist * chore: Add in the baseDist * chore: Get the web and the runtime-container running * chore: Remove the empty file * chore: Fix it so the container-runtime works --------- Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com> Co-authored-by: Aiden McClelland <me@drbonez.dev> * misc fixes * update todos * minor clean up * fix link script * update node version in CI test * fix node version syntax in ci build * wip: fixing callbacks * fix sdk makefile dependencies * add support for const outside of main * update apis * don't panic! * Chore: Capture weird case on rpc, and log that * fix procedure id issue * pass input value for dep auto config * handle disabled and warning for actions * chore: Fix for link not having node_modules * sdk fixes * fix build * fix build * fix build --------- Co-authored-by: Matt Hill <mattnine@protonmail.com> Co-authored-by: Jade <Blu-J@users.noreply.github.com> Co-authored-by: J H <dragondef@gmail.com> Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com> Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
204 lines
6.5 KiB
TypeScript
204 lines
6.5 KiB
TypeScript
import { ExtendedVersion, VersionRange } from "../../../base/lib/exver"
|
|
import * as T from "../../../base/lib/types"
|
|
import { Graph, Vertex, once } from "../util"
|
|
import { IMPOSSIBLE, VersionInfo } from "./VersionInfo"
|
|
|
|
export class VersionGraph<CurrentVersion extends string> {
|
|
private readonly graph: () => Graph<
|
|
ExtendedVersion | VersionRange,
|
|
((opts: { effects: T.Effects }) => Promise<void>) | undefined
|
|
>
|
|
private constructor(
|
|
readonly current: VersionInfo<CurrentVersion>,
|
|
versions: Array<VersionInfo<any>>,
|
|
) {
|
|
this.graph = once(() => {
|
|
const graph = new Graph<
|
|
ExtendedVersion | VersionRange,
|
|
((opts: { effects: T.Effects }) => Promise<void>) | undefined
|
|
>()
|
|
const flavorMap: Record<
|
|
string,
|
|
[
|
|
ExtendedVersion,
|
|
VersionInfo<any>,
|
|
Vertex<
|
|
ExtendedVersion | VersionRange,
|
|
((opts: { effects: T.Effects }) => Promise<void>) | undefined
|
|
>,
|
|
][]
|
|
> = {}
|
|
for (let version of [current, ...versions]) {
|
|
const v = ExtendedVersion.parse(version.options.version)
|
|
const vertex = graph.addVertex(v, [], [])
|
|
const flavor = v.flavor || ""
|
|
if (!flavorMap[flavor]) {
|
|
flavorMap[flavor] = []
|
|
}
|
|
flavorMap[flavor].push([v, version, vertex])
|
|
}
|
|
for (let flavor in flavorMap) {
|
|
flavorMap[flavor].sort((a, b) => a[0].compareForSort(b[0]))
|
|
let prev:
|
|
| [
|
|
ExtendedVersion,
|
|
VersionInfo<any>,
|
|
Vertex<
|
|
ExtendedVersion | VersionRange,
|
|
(opts: { effects: T.Effects }) => Promise<void>
|
|
>,
|
|
]
|
|
| undefined = undefined
|
|
for (let [v, version, vertex] of flavorMap[flavor]) {
|
|
if (version.options.migrations.up !== IMPOSSIBLE) {
|
|
let range
|
|
if (prev) {
|
|
graph.addEdge(version.options.migrations.up, prev[2], vertex)
|
|
range = VersionRange.anchor(">=", prev[0]).and(
|
|
VersionRange.anchor("<", v),
|
|
)
|
|
} else {
|
|
range = VersionRange.anchor("<", v)
|
|
}
|
|
const vRange = graph.addVertex(range, [], [])
|
|
graph.addEdge(version.options.migrations.up, vRange, vertex)
|
|
}
|
|
|
|
if (version.options.migrations.down !== IMPOSSIBLE) {
|
|
let range
|
|
if (prev) {
|
|
graph.addEdge(version.options.migrations.down, vertex, prev[2])
|
|
range = VersionRange.anchor(">=", prev[0]).and(
|
|
VersionRange.anchor("<", v),
|
|
)
|
|
} else {
|
|
range = VersionRange.anchor("<", v)
|
|
}
|
|
const vRange = graph.addVertex(range, [], [])
|
|
graph.addEdge(version.options.migrations.down, vertex, vRange)
|
|
}
|
|
|
|
if (version.options.migrations.other) {
|
|
for (let rangeStr in version.options.migrations.other) {
|
|
const range = VersionRange.parse(rangeStr)
|
|
const vRange = graph.addVertex(range, [], [])
|
|
graph.addEdge(
|
|
version.options.migrations.other[rangeStr],
|
|
vRange,
|
|
vertex,
|
|
)
|
|
for (let matching of graph.findVertex(
|
|
(v) =>
|
|
v.metadata instanceof ExtendedVersion &&
|
|
v.metadata.satisfies(range),
|
|
)) {
|
|
graph.addEdge(
|
|
version.options.migrations.other[rangeStr],
|
|
matching,
|
|
vertex,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return graph
|
|
})
|
|
}
|
|
currentVersion = once(() =>
|
|
ExtendedVersion.parse(this.current.options.version),
|
|
)
|
|
/**
|
|
* Each exported `VersionInfo.of()` should be imported and provided as an argument to this function.
|
|
*
|
|
* ** The current version must be the FIRST argument. **
|
|
*/
|
|
static of<
|
|
CurrentVersion extends string,
|
|
OtherVersions extends Array<VersionInfo<any>>,
|
|
>(
|
|
currentVersion: VersionInfo<CurrentVersion>,
|
|
...other: EnsureUniqueId<OtherVersions, OtherVersions, CurrentVersion>
|
|
) {
|
|
return new VersionGraph(currentVersion, other as Array<VersionInfo<any>>)
|
|
}
|
|
async migrate({
|
|
effects,
|
|
from,
|
|
to,
|
|
}: {
|
|
effects: T.Effects
|
|
from: ExtendedVersion
|
|
to: ExtendedVersion
|
|
}) {
|
|
const graph = this.graph()
|
|
if (from && to) {
|
|
const path = graph.shortestPath(
|
|
(v) =>
|
|
(v.metadata instanceof VersionRange &&
|
|
v.metadata.satisfiedBy(from)) ||
|
|
(v.metadata instanceof ExtendedVersion && v.metadata.equals(from)),
|
|
(v) =>
|
|
(v.metadata instanceof VersionRange && v.metadata.satisfiedBy(to)) ||
|
|
(v.metadata instanceof ExtendedVersion && v.metadata.equals(to)),
|
|
)
|
|
if (path) {
|
|
for (let edge of path) {
|
|
if (edge.metadata) {
|
|
await edge.metadata({ effects })
|
|
}
|
|
await effects.setDataVersion({ version: edge.to.metadata.toString() })
|
|
}
|
|
return
|
|
}
|
|
}
|
|
throw new Error()
|
|
}
|
|
canMigrateFrom = once(() =>
|
|
Array.from(
|
|
this.graph().reverseBreadthFirstSearch(
|
|
(v) =>
|
|
(v.metadata instanceof VersionRange &&
|
|
v.metadata.satisfiedBy(this.currentVersion())) ||
|
|
(v.metadata instanceof ExtendedVersion &&
|
|
v.metadata.equals(this.currentVersion())),
|
|
),
|
|
).reduce(
|
|
(acc, x) =>
|
|
acc.or(
|
|
x.metadata instanceof VersionRange
|
|
? x.metadata
|
|
: VersionRange.anchor("=", x.metadata),
|
|
),
|
|
VersionRange.none(),
|
|
),
|
|
)
|
|
canMigrateTo = once(() =>
|
|
Array.from(
|
|
this.graph().breadthFirstSearch(
|
|
(v) =>
|
|
(v.metadata instanceof VersionRange &&
|
|
v.metadata.satisfiedBy(this.currentVersion())) ||
|
|
(v.metadata instanceof ExtendedVersion &&
|
|
v.metadata.equals(this.currentVersion())),
|
|
),
|
|
).reduce(
|
|
(acc, x) =>
|
|
acc.or(
|
|
x.metadata instanceof VersionRange
|
|
? x.metadata
|
|
: VersionRange.anchor("=", x.metadata),
|
|
),
|
|
VersionRange.none(),
|
|
),
|
|
)
|
|
}
|
|
|
|
// prettier-ignore
|
|
export type EnsureUniqueId<A, B = A, OtherVersions = never> =
|
|
B extends [] ? A :
|
|
B extends [VersionInfo<infer Version>, ...infer Rest] ? (
|
|
Version extends OtherVersions ? "One or more versions are not unique"[] :
|
|
EnsureUniqueId<A, Rest, Version | OtherVersions>
|
|
) : "There exists a migration that is not a Migration"[]
|