mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
* feat(sdk): session API, optional history + persist-queue, adapters — Phase 3a complete * fix(sdk): address review — live-DOM query cache, single parse, style parse dedup - getElements/getElement/find now walk the live linkedom DOM via buildRoots with a lazily-built cache invalidated on dispatch/applyPatches — no serialize→ensureHfIds→parseHTML round trip per query - openComposition parses once (parseMutable); dropped discarded _doc constructor param and the redundant buildDocument call - document.ts buildElement reuses model.ts getElementStyles — removes duplicated parseInlineStyles (also fixes custom-prop camelCase mangling) - JSDoc note: empty batch() still fires change handlers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sdk): restore full public exports now session/document modules exist index.ts re-exports document/session/history/persist-queue (trimmed in the engine-layer PR to keep it self-contained); drops the temporary fallow suppressions whose consumers now exist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sdk): coalesce history by patch paths; replay override-set on open Adversarial-review findings F1 + F2: - history: coalescing now requires identical patch paths in addition to op types + origin + window. Previously two rapid setStyle calls on DIFFERENT elements merged into one entry carrying the second forward + first inverse — undo then reverted the wrong element and stranded the latest edit. Slider drags on one property still coalesce. - T3 init: openComposition({ overrides }) now replays the stored override-set onto the freshly-parsed base before exposing the session (new keyToPath inverse mapping + applyOverrideSet). Previously the overrides were copied into the map but never applied — reopening an embedded composition showed and serialized the base template. - examples: GSAP calls now feature-detect with can() (Phase 3b ops throw UnsupportedOpError as of the engine-layer fix); UnsupportedOpError re-exported from the package entry. - 8 new session tests: coalesce same-path / cross-element / cross-prop, override round-trip (style/text/attr/timing/removal/restore-base). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sdk): transactional batch rollback, sorted coalesce key, root-priority unify Round-2 review (Rames/Miguel) on the session layer: - batch() is now transactional: on throw, accumulated inverse patches are replayed in reverse and the override-set snapshot restored — the model is exactly as it was at batch entry. Previously a throwing batch left the DOM partially mutated with no patch trail, no history entry, no recovery path. 2 new tests (model unchanged + undo is no-op after throwing batch). - history coalesce key sorts opTypes — same op-type set coalesces regardless of dispatch order within a batch. - applyPatches comment documents that emitted PatchEvents carry an empty inversePatches array (hosts keep their own inverse log). - document.ts extractDimensions/extractDuration now use the engine's findRoot — dimension extraction and mutations agree on the root element ([data-hf-root] > #stage > first child). Dimensions prefer the runtime's data-width/data-height forced-override attrs, falling back to inline style. - ownText documented: snapshot .text is trimmed display text; setText writes verbatim. Deferred to follow-up (acknowledged, not ship-blocking): persist-queue flush error surfacing, debounce window, path default, history ring-buffer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import type { PersistAdapter, PersistVersionEntry } from "./types.js";
|
|
import type { PersistErrorEvent } from "../types.js";
|
|
|
|
export interface FsAdapterOptions {
|
|
/** Root directory for composition files */
|
|
root: string;
|
|
}
|
|
|
|
// Phase 4 — fs adapter stub. Full implementation in SDK Phase 4 (adapters stage).
|
|
// Uses Node.js fs/promises; not browser-safe (must be conditionally imported by consumers).
|
|
|
|
class FsAdapter implements PersistAdapter {
|
|
private readonly root: string;
|
|
|
|
constructor(opts: FsAdapterOptions) {
|
|
this.root = opts.root;
|
|
}
|
|
|
|
async read(_path: string): Promise<string | undefined> {
|
|
throw new Error("FsAdapter: Phase 4 — not yet implemented");
|
|
}
|
|
|
|
async write(_path: string, _content: string): Promise<void> {
|
|
throw new Error("FsAdapter: Phase 4 — not yet implemented");
|
|
}
|
|
|
|
async flush(): Promise<void> {
|
|
throw new Error("FsAdapter: Phase 4 — not yet implemented");
|
|
}
|
|
|
|
async listVersions(_path: string): Promise<PersistVersionEntry[]> {
|
|
throw new Error("FsAdapter: Phase 4 — not yet implemented");
|
|
}
|
|
|
|
async loadFrom(_path: string, _versionKey: string): Promise<string | undefined> {
|
|
throw new Error("FsAdapter: Phase 4 — not yet implemented");
|
|
}
|
|
|
|
on(_event: "persist:error", _handler: (e: PersistErrorEvent) => void): () => void {
|
|
return () => {};
|
|
}
|
|
}
|
|
|
|
export function createFsAdapter(opts: FsAdapterOptions): PersistAdapter {
|
|
return new FsAdapter(opts);
|
|
}
|