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 // prioritize ArkType's "type" for autoimports
"typescript.preferences.autoImportSpecifierExcludeRegexes": [ "typescript.preferences.autoImportSpecifierExcludeRegexes": [
"^(node:)?os$" "^(node:)?os$"
] ],
"typescript.tsdk": "node_modules/typescript/lib"
} }

View File

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

View File

View File

@ -2,7 +2,6 @@ import {
type EbmlTagType, type EbmlTagType,
EbmlTagIdEnum, EbmlTagIdEnum,
EbmlTagPosition, EbmlTagPosition,
type EbmlCuePointTagType,
type EbmlTracksTagType, type EbmlTracksTagType,
type EbmlInfoTagType, type EbmlInfoTagType,
type EbmlCuesTagType, type EbmlCuesTagType,
@ -127,13 +126,11 @@ export class TrackEntry extends TagWithArktype({
}), }),
}) {} }) {}
const TracksSchema = type({
tracks: type.instanceOf(TrackEntry).array(),
});
export class Tracks extends TagWithArktype({ export class Tracks extends TagWithArktype({
id: EbmlTagIdEnum.Tracks, id: EbmlTagIdEnum.Tracks,
schema: TracksSchema, schema: type({
tracks: type.instanceOf(TrackEntry).array(),
}),
extract: simpleMasterExtractor({ extract: simpleMasterExtractor({
[EbmlTagIdEnum.TrackEntry]: { [EbmlTagIdEnum.TrackEntry]: {
key: 'tracks', key: 'tracks',
@ -148,13 +145,11 @@ export interface EbmlSeekEntry {
seekPosition: number; seekPosition: number;
} }
export class EbmlHead { export class MHead extends TagWithArktype({
head: EbmlTagType; id: EbmlTagIdEnum.EBML,
schema: type({}),
constructor(head: EbmlTagType) { extract: () => ({}),
this.head = head; }) {}
}
}
export class SimpleBlock extends TagWithArktype({ export class SimpleBlock extends TagWithArktype({
id: EbmlTagIdEnum.SimpleBlock, 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({ export class Cluster extends TagWithArktype({
id: EbmlTagIdEnum.Cluster, id: EbmlTagIdEnum.Cluster,
schema: type({ schema: type({
@ -191,88 +192,16 @@ export class Cluster extends TagWithArktype({
}), }),
}) {} }) {}
export interface TrackPositions { export type CuePointType = typeof CuePoint.infer;
track: number;
clusterPosition: number;
relativePosition?: number;
duration?: number;
}
export class CuePoint { export class Cues {
node: EbmlCuePointTagType; cues: CuePointType[];
_timestamp: number;
trackPositions: TrackPositions[];
get timestamp(): number { constructor(
return this._timestamp; 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 { findClosestCue(seekTime: number): CuePoint | null {
const cues = this.cues; const cues = this.cues;
if (!cues || cues.length === 0) { if (!cues || cues.length === 0) {
@ -282,22 +211,22 @@ export class Cues extends TagWithArktype({
let left = 0; let left = 0;
let right = cues.length - 1; let right = cues.length - 1;
if (seekTime <= cues[0].timestamp) { if (seekTime <= cues[0].CueTime) {
return cues[0]; return cues[0];
} }
if (seekTime >= cues[right].timestamp) { if (seekTime >= cues[right].CueTime) {
return cues[right]; return cues[right];
} }
while (left <= right) { while (left <= right) {
const mid = Math.floor((left + right) / 2); const mid = Math.floor((left + right) / 2);
if (cues[mid].timestamp === seekTime) { if (cues[mid].CueTime === seekTime) {
return cues[mid]; return cues[mid];
} }
if (cues[mid].timestamp < seekTime) { if (cues[mid].CueTime < seekTime) {
left = mid + 1; left = mid + 1;
} else { } else {
right = mid - 1; 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 type InferType<T> = T extends Type<infer U> ? U : never;
export interface TagWithArktypeOptions< export interface TagWithArktypeOptions<
I extends EbmlTagType['id'], T extends EbmlTagType,
S extends Type<any>, S extends Type<any>,
> { > {
id: I; id: T['id'];
schema: S; schema: S;
extract: (tag: Extract<EbmlTagType, { id: I }>, schema: S) => InferType<S>; extract: (tag: T, schema: S) => InferType<S>;
} }
export type TagWithArktypeClassInstance< export type TagWithArktypeClassInstance<
I extends EbmlTagType['id'], T extends EbmlTagType,
S extends Type<any>, S extends Type<any>,
> = InferType<S> & { > = InferType<S> & {
tag: Extract<EbmlTagType, { id: I }>; tag: T;
}; };
export interface TagWithArktypeClass< export interface TagWithArktypeClass<
I extends EbmlTagType['id'], T extends EbmlTagType,
S extends Type<any>, S extends Type<any>,
> { > {
new ( new (tag: T, validatedTag: InferType<S>): TagWithArktypeClassInstance<T, S>;
tag: Extract<EbmlTagType, { id: I }>,
validatedTag: InferType<S>
): TagWithArktypeClassInstance<I, S>;
fromTag<R extends TagWithArktypeClassInstance<I, S>>( fromTag<R extends TagWithArktypeClassInstance<T, S>>(
this: new ( this: new (
tag: Extract<EbmlTagType, { id: I }>, tag: T,
validatedTag: InferType<S> validatedTag: InferType<S>
) => TagWithArktypeClassInstance<I, S>, ) => TagWithArktypeClassInstance<T, S>,
tag: Extract<EbmlTagType, { id: I }> tag: T
): R; ): R;
id: I; id: T['id'];
schema: S; schema: S;
} }
export function TagWithArktype< export function TagWithArktype<T extends EbmlTagType, S extends Type<any>>({
I extends EbmlTagType['id'],
S extends Type<any>,
>({
id, id,
schema, schema,
extract, extract,
}: TagWithArktypeOptions<I, S>): TagWithArktypeClass<I, S> { }: TagWithArktypeOptions<T, S>): TagWithArktypeClass<T, S> {
const tagWithArktypeImpl = class TagWithArktypeImpl { const tagWithArktypeImpl = class TagWithArktypeImpl {
static id = id; static id = id;
static schema = schema; static schema = schema;
tag: Extract<EbmlTagType, { id: I }>; tag: T;
constructor( constructor(tag: T, validatedTag: InferType<S>) {
tag: Extract<EbmlTagType, { id: I }>,
validatedTag: InferType<S>
) {
Object.assign(this, validatedTag); Object.assign(this, validatedTag);
this.tag = tag; this.tag = tag;
} }
static fromTag(tag: Extract<EbmlTagType, { id: I }>) { static fromTag(tag: T) {
const extractedData = extract(tag, schema); const extractedData = extract(tag, schema);
const validatedExtractedData = schema(extractedData); const validatedExtractedData = schema(extractedData);
// biome-ignore lint/complexity/noThisInStatic: <explanation> // 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 }>; export type PredicateIdExtract<T, K> = Extract<T, { id: K }>;

View File

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

17
pnpm-lock.yaml generated
View File

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