feat(packages): add mux media with src parsing, structured source, and storyboards (#1850)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Wesley Luyten
2026-07-27 16:55:24 -07:00
committed by GitHub
co-authored by Claude
parent fd4d2662ea
commit 409e7ef225
29 changed files with 1519 additions and 41 deletions
+1
View File
@@ -0,0 +1 @@
export * from './parse-jwt';
+18
View File
@@ -0,0 +1,18 @@
/** Decode the payload of a JWT without verifying its signature, `undefined` for malformed tokens. */
export function parseJwt<Payload = Record<string, unknown>>(token: string | undefined): Partial<Payload> | undefined {
const base64Url = (token ?? '').split('.')[1];
if (!base64Url) return undefined;
try {
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const json = decodeURIComponent(
atob(base64)
.split('')
.map((char) => `%${`00${char.charCodeAt(0).toString(16)}`.slice(-2)}`)
.join('')
);
return JSON.parse(json);
} catch {
return undefined;
}
}
@@ -0,0 +1,28 @@
import { describe, expect, it } from 'vitest';
import { parseJwt } from '../parse-jwt';
// Header `{"alg":"HS256"}`, body is the payload (UTF-8), empty signature.
function fakeJwt(payload: Record<string, unknown>): string {
const encode = (obj: unknown) =>
btoa(String.fromCharCode(...new TextEncoder().encode(JSON.stringify(obj))))
.replace(/\+/g, '-')
.replace(/\//g, '_');
return `${encode({ alg: 'HS256' })}.${encode(payload)}.`;
}
describe('parseJwt', () => {
it('decodes a token payload', () => {
expect(parseJwt(fakeJwt({ aud: 'v', sub: 'abc' }))).toMatchObject({ aud: 'v', sub: 'abc' });
});
it('decodes unicode payload values', () => {
expect(parseJwt(fakeJwt({ sub: 'vidéo' }))).toMatchObject({ sub: 'vidéo' });
});
it('returns undefined for invalid tokens', () => {
expect(parseJwt(undefined)).toBeUndefined();
expect(parseJwt('')).toBeUndefined();
expect(parseJwt('not-a-jwt')).toBeUndefined();
expect(parseJwt('a.%%%.c')).toBeUndefined();
});
});
+29
View File
@@ -0,0 +1,29 @@
import { isPlainObject, isUndefined } from '../predicate';
/**
* Deep structural equality for plain objects, arrays, and primitives. Keys
* explicitly set to `undefined` are treated as absent (matching JSON
* semantics), leaf values are compared with `Object.is`, and non-plain
* objects (class instances, Maps, Sets, etc.) are only equal by reference.
*
* @example
* ```ts
* deepEqual({ a: [1, { b: 2 }] }, { a: [1, { b: 2 }] }); // true
* deepEqual({ a: 1, b: undefined }, { a: 1 }); // true
* ```
*/
export function deepEqual(a: unknown, b: unknown): boolean {
if (Object.is(a, b)) return true;
if (Array.isArray(a) || Array.isArray(b)) {
return (
Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((value, i) => deepEqual(value, b[i]))
);
}
if (!isPlainObject(a) || !isPlainObject(b)) return false;
const keysA = Object.keys(a).filter((key) => !isUndefined(a[key]));
const keysB = Object.keys(b).filter((key) => !isUndefined(b[key]));
return keysA.length === keysB.length && keysA.every((key) => deepEqual(a[key], b[key]));
}
+1
View File
@@ -1,3 +1,4 @@
export { deepEqual } from './deep-equal';
export { defaults } from './defaults';
export { omit } from './omit';
export { pick } from './pick';
@@ -0,0 +1,65 @@
import { describe, expect, it } from 'vitest';
import { deepEqual } from '../deep-equal';
describe('deepEqual', () => {
it('returns true for identical primitives', () => {
expect(deepEqual(1, 1)).toBe(true);
expect(deepEqual('a', 'a')).toBe(true);
expect(deepEqual(true, true)).toBe(true);
expect(deepEqual(null, null)).toBe(true);
expect(deepEqual(undefined, undefined)).toBe(true);
});
it('returns false for different primitives', () => {
expect(deepEqual(1, 2)).toBe(false);
expect(deepEqual('a', 'b')).toBe(false);
expect(deepEqual(null, undefined)).toBe(false);
expect(deepEqual(0, '0')).toBe(false);
});
it('returns true for same reference', () => {
const obj = { a: { b: 1 } };
expect(deepEqual(obj, obj)).toBe(true);
});
it('compares nested objects structurally', () => {
expect(deepEqual({ a: { b: 1 } }, { a: { b: 1 } })).toBe(true);
expect(deepEqual({ a: { b: 1 } }, { a: { b: 2 } })).toBe(false);
expect(deepEqual({ a: { b: 1 } }, { a: { c: 1 } })).toBe(false);
});
it('compares arrays structurally', () => {
expect(deepEqual([1, 2, 3], [1, 2, 3])).toBe(true);
expect(deepEqual([1, 2, 3], [1, 2])).toBe(false);
expect(deepEqual([1, 2, 3], [3, 2, 1])).toBe(false);
expect(deepEqual([{ a: 1 }], [{ a: 1 }])).toBe(true);
expect(deepEqual([], {})).toBe(false);
});
it('returns false for objects with different keys', () => {
expect(deepEqual({ a: 1 }, { a: 1, b: 2 })).toBe(false);
});
it('treats keys set to undefined as absent', () => {
expect(deepEqual({ a: 1, b: undefined }, { a: 1 })).toBe(true);
expect(deepEqual({ a: undefined }, {})).toBe(true);
expect(deepEqual({ a: null }, {})).toBe(false);
});
it('handles NaN and signed zero like Object.is', () => {
expect(deepEqual({ a: NaN }, { a: NaN })).toBe(true);
expect(deepEqual({ a: 0 }, { a: -0 })).toBe(false);
});
it('compares non-plain objects by reference only', () => {
const date = new Date(0);
expect(deepEqual(date, date)).toBe(true);
expect(deepEqual(new Date(0), new Date(0))).toBe(false);
expect(deepEqual(new Map(), new Map())).toBe(false);
});
it('returns false when comparing object to primitive or null', () => {
expect(deepEqual({ a: 1 }, null)).toBe(false);
expect(deepEqual({ a: 1 }, 1)).toBe(false);
});
});
+4
View File
@@ -9,3 +9,7 @@ export function camelCase(str: string): string {
export function kebabCase(str: string): string {
return str.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
}
export function snakeCase(str: string): string {
return str.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
}
+11 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { camelCase, kebabCase, pascalCase } from '../casing';
import { camelCase, kebabCase, pascalCase, snakeCase } from '../casing';
describe('casing', () => {
describe('pascalCase', () => {
@@ -42,6 +42,16 @@ describe('casing', () => {
});
});
describe('snakeCase', () => {
it('converts camelCase', () => {
expect(snakeCase('assetStartTime')).toBe('asset_start_time');
});
it('preserves lowercase', () => {
expect(snakeCase('token')).toBe('token');
});
});
describe('kebabCase', () => {
it('converts camelCase', () => {
expect(kebabCase('positionAnchor')).toBe('position-anchor');