feat: temp save

This commit is contained in:
master 2025-03-21 13:54:39 +08:00
parent 4537190096
commit d7b8b57e9c
8 changed files with 62 additions and 130 deletions

View File

@ -6,5 +6,6 @@
// prioritize ArkType's "type" for autoimports
"typescript.preferences.autoImportSpecifierExcludeRegexes": [
"^(node:)?os$"
]
],
"typescript.tsdk": "node_modules/typescript/lib"
}

View File

@ -9,7 +9,7 @@
"preview": "rsbuild preview"
},
"dependencies": {
"konoebml": "0.1.0-rc.8",
"konoebml": "0.1.0",
"lit": "^3.2.1"
},
"devDependencies": {

View File

View File

@ -2,7 +2,6 @@ import {
type EbmlTagType,
EbmlTagIdEnum,
EbmlTagPosition,
type EbmlCuePointTagType,
type EbmlTracksTagType,
type EbmlInfoTagType,
type EbmlCuesTagType,
@ -127,13 +126,11 @@ export class TrackEntry extends TagWithArktype({
}),
}) {}
const TracksSchema = type({
tracks: type.instanceOf(TrackEntry).array(),
});
export class Tracks extends TagWithArktype({
id: EbmlTagIdEnum.Tracks,
schema: TracksSchema,
schema: type({
tracks: type.instanceOf(TrackEntry).array(),
}),
extract: simpleMasterExtractor({
[EbmlTagIdEnum.TrackEntry]: {
key: 'tracks',
@ -148,13 +145,11 @@ export interface EbmlSeekEntry {
seekPosition: number;
}
export class EbmlHead {
head: EbmlTagType;
constructor(head: EbmlTagType) {
this.head = head;
}
}
export class MHead extends TagWithArktype({
id: EbmlTagIdEnum.EBML,
schema: type({}),
extract: () => ({}),
}) {}
export class SimpleBlock extends TagWithArktype({
id: EbmlTagIdEnum.SimpleBlock,
@ -166,6 +161,12 @@ export class SimpleBlock extends TagWithArktype({
}),
}) {}
export class Block extends TagWithArktype({
id: EbmlTagIdEnum.Block,
schema: type({}),
extract: () => ({}),
}) {}
export class Cluster extends TagWithArktype({
id: EbmlTagIdEnum.Cluster,
schema: type({
@ -191,88 +192,16 @@ export class Cluster extends TagWithArktype({
}),
}) {}
export interface TrackPositions {
track: number;
clusterPosition: number;
relativePosition?: number;
duration?: number;
}
export type CuePointType = typeof CuePoint.infer;
export class CuePoint {
node: EbmlCuePointTagType;
_timestamp: number;
trackPositions: TrackPositions[];
export class Cues {
cues: CuePointType[];
get timestamp(): number {
return this._timestamp;
}
constructor(
public readonly tag: EbmlCuesTagType,
cues: CuePointType[]
) {}
get position(): number {
return Math.max(...this.trackPositions.map((t) => t.clusterPosition));
}
constructor(node: EbmlCuePointTagType) {
this.node = node;
this._timestamp = node.children.find((c) => c.id === EbmlTagIdEnum.CueTime)
?.data as number;
this.trackPositions = node.children
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
.map((t) => {
if (
t.id === EbmlTagIdEnum.CueTrackPositions &&
t.position === EbmlTagPosition.End
) {
let track!: number;
let clusterPosition!: number;
let relativePosition: number | undefined;
let duration: number | undefined;
for (const c of t.children) {
if (c.id === EbmlTagIdEnum.CueTrack) {
track = c.data as number;
}
if (c.id === EbmlTagIdEnum.CueClusterPosition) {
clusterPosition = c.data as number;
}
if (c.id === EbmlTagIdEnum.CueRelativePosition) {
relativePosition = c.data as number;
}
if (c.id === EbmlTagIdEnum.CueDuration) {
duration = c.data as number;
}
}
if (track! >= 0 && clusterPosition! >= 0) {
return {
track: track!,
clusterPosition: clusterPosition!,
relativePosition,
duration,
} as TrackPositions;
}
throw new Error(
`Tracking positions missing track of cluster position at ${t.startOffset}`
);
}
return null;
})
.filter((a): a is TrackPositions => !!a);
}
}
export class Cues extends TagWithArktype({
id: EbmlTagIdEnum.Cues,
schema: type({
cues: type.instanceOf(CuePoint).array(),
}),
extract: simpleMasterExtractor({
[EbmlTagIdEnum.CuePoint]: {
key: 'cues',
multi: true,
extract: (t) => new CuePoint(t),
},
}),
}) {
findClosestCue(seekTime: number): CuePoint | null {
const cues = this.cues;
if (!cues || cues.length === 0) {
@ -282,22 +211,22 @@ export class Cues extends TagWithArktype({
let left = 0;
let right = cues.length - 1;
if (seekTime <= cues[0].timestamp) {
if (seekTime <= cues[0].CueTime) {
return cues[0];
}
if (seekTime >= cues[right].timestamp) {
if (seekTime >= cues[right].CueTime) {
return cues[right];
}
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (cues[mid].timestamp === seekTime) {
if (cues[mid].CueTime === seekTime) {
return cues[mid];
}
if (cues[mid].timestamp < seekTime) {
if (cues[mid].CueTime < seekTime) {
left = mid + 1;
} else {
right = mid - 1;

View File

View File

@ -4,65 +4,56 @@ import type { EbmlMasterTagType, EbmlTagIdEnum, EbmlTagType } from 'konoebml';
export type InferType<T> = T extends Type<infer U> ? U : never;
export interface TagWithArktypeOptions<
I extends EbmlTagType['id'],
T extends EbmlTagType,
S extends Type<any>,
> {
id: I;
id: T['id'];
schema: S;
extract: (tag: Extract<EbmlTagType, { id: I }>, schema: S) => InferType<S>;
extract: (tag: T, schema: S) => InferType<S>;
}
export type TagWithArktypeClassInstance<
I extends EbmlTagType['id'],
T extends EbmlTagType,
S extends Type<any>,
> = InferType<S> & {
tag: Extract<EbmlTagType, { id: I }>;
tag: T;
};
export interface TagWithArktypeClass<
I extends EbmlTagType['id'],
T extends EbmlTagType,
S extends Type<any>,
> {
new (
tag: Extract<EbmlTagType, { id: I }>,
validatedTag: InferType<S>
): TagWithArktypeClassInstance<I, S>;
new (tag: T, validatedTag: InferType<S>): TagWithArktypeClassInstance<T, S>;
fromTag<R extends TagWithArktypeClassInstance<I, S>>(
fromTag<R extends TagWithArktypeClassInstance<T, S>>(
this: new (
tag: Extract<EbmlTagType, { id: I }>,
tag: T,
validatedTag: InferType<S>
) => TagWithArktypeClassInstance<I, S>,
tag: Extract<EbmlTagType, { id: I }>
) => TagWithArktypeClassInstance<T, S>,
tag: T
): R;
id: I;
id: T['id'];
schema: S;
}
export function TagWithArktype<
I extends EbmlTagType['id'],
S extends Type<any>,
>({
export function TagWithArktype<T extends EbmlTagType, S extends Type<any>>({
id,
schema,
extract,
}: TagWithArktypeOptions<I, S>): TagWithArktypeClass<I, S> {
}: TagWithArktypeOptions<T, S>): TagWithArktypeClass<T, S> {
const tagWithArktypeImpl = class TagWithArktypeImpl {
static id = id;
static schema = schema;
tag: Extract<EbmlTagType, { id: I }>;
tag: T;
constructor(
tag: Extract<EbmlTagType, { id: I }>,
validatedTag: InferType<S>
) {
constructor(tag: T, validatedTag: InferType<S>) {
Object.assign(this, validatedTag);
this.tag = tag;
}
static fromTag(tag: Extract<EbmlTagType, { id: I }>) {
static fromTag(tag: T) {
const extractedData = extract(tag, schema);
const validatedExtractedData = schema(extractedData);
// biome-ignore lint/complexity/noThisInStatic: <explanation>
@ -70,7 +61,7 @@ export function TagWithArktype<
}
};
return tagWithArktypeImpl as unknown as TagWithArktypeClass<I, S>;
return tagWithArktypeImpl as unknown as TagWithArktypeClass<T, S>;
}
export type PredicateIdExtract<T, K> = Extract<T, { id: K }>;

View File

@ -6,6 +6,7 @@
"linter": {
"rules": {
"style": {
"noParameterProperties": "off",
"noNonNullAssertion": "off"
},
"suspicious": {
@ -16,6 +17,9 @@
},
"complexity": {
"noBannedTypes": "off"
},
"nursery": {
"useConsistentMemberAccessibility": "off"
}
}
},

17
pnpm-lock.yaml generated
View File

@ -80,8 +80,8 @@ importers:
apps/playground:
dependencies:
konoebml:
specifier: 0.1.0-rc.8
version: 0.1.0-rc.8
specifier: 0.1.0
version: 0.1.0(arktype@2.1.10)
lit:
specifier: ^3.2.1
version: 3.2.1
@ -1853,9 +1853,14 @@ packages:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
konoebml@0.1.0-rc.8:
resolution: {integrity: sha512-fR4DZqCskLKxGBMc58gpOOzajFrfu9hQC7WZd8yGiIxLVhDkzBnihXqlsWJU6Qw77ukMOGGkbeM2uqQyv5dO3w==}
konoebml@0.1.0:
resolution: {integrity: sha512-Fp4nJBr9E82sr2Ap0JwHZFoeyNH7Cy0NdVXRcJ54wxCNfs3MHfo9IXnSLph/zvkGT1b5qw7JSs4nwoygZF4F7g==}
engines: {node: '>= 18.0.0'}
peerDependencies:
arktype: ^2.0.0
peerDependenciesMeta:
arktype:
optional: true
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@ -4462,10 +4467,12 @@ snapshots:
kind-of@6.0.3: {}
konoebml@0.1.0-rc.8:
konoebml@0.1.0(arktype@2.1.10):
dependencies:
mnemonist: 0.40.3
type-fest: 4.37.0
optionalDependencies:
arktype: 2.1.10
lines-and-columns@1.2.4: {}