MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / _dispatch

Method _dispatch

packages/sdk/src/session.ts:389–447  ·  view source on GitHub ↗
(op: EditOp, origin: unknown)

Source from the content-addressed store, hash-verified

387
388 // fallow-ignore-next-line complexity
389 private _dispatch(op: EditOp, origin: unknown): MutationResult {
390 const result = applyOp(this.parsed, op);
391 const { forward, inverse } = result;
392
393 if (forward.length === 0 && inverse.length === 0) {
394 if (this.batchDepth === 0) this.changeHandlers.forEach((h) => h());
395 return result;
396 }
397
398 this.elementsCache = null;
399
400 // Update override-set from forward patches
401 for (const p of forward) {
402 const key = pathToKey(p.path);
403 if (key !== null) {
404 this.overrides[key] =
405 p.op === "remove"
406 ? null
407 : (p.value as string | number | boolean | Record<string, unknown> | null);
408 }
409 }
410
411 // Purge orphan property keys for removed elements so the override-set stays
412 // compact and a future T3 session doesn't replay stale properties onto a
413 // non-existent element. Override-set keys use decoded scoped ids ("hf-host/hf-leaf")
414 // while path segments use RFC 6902 encoding ("hf-host~1hf-leaf") — decode before compare.
415 for (const p of forward) {
416 const elemMatch = /^\/elements\/([^/]+)$/.exec(p.path);
417 if (p.op === "remove" && elemMatch) {
418 // Decode RFC 6902 escaping: ~1 → /, ~0 → ~
419 const id = elemMatch[1]!.replace(/~1/g, "/").replace(/~0/g, "~");
420 for (const key of Object.keys(this.overrides)) {
421 // Purge property sub-keys (e.g. "hf-x.style.color") but preserve
422 // the removal marker itself (key === id, set to null in the loop above).
423 if (key.startsWith(`${id}.`) || key.startsWith(`${id}/`)) {
424 delete this.overrides[key];
425 }
426 }
427 }
428 }
429
430 if (this.batchDepth > 0) {
431 this.batchForward.push(...forward);
432 this.batchInverse.push(...inverse);
433 if (!this.batchOpTypes.includes(op.type)) this.batchOpTypes.push(op.type);
434 } else {
435 // Reverse the inverse list (parity with batch() below): an op that emits
436 // multiple patches whose undo order matters — same path (reorderElements
437 // with a duplicate target), an aliased multi-target, or a nested
438 // parent+child removeElement — must undo in reverse application order, or
439 // undo lands on an intermediate value / drops a subtree. Harmless for the
440 // common single-patch / independent-path case.
441 const event = buildPatchEvent(forward, [...inverse].reverse(), origin, [op.type]);
442 this.patchHandlers.forEach((h) => h(event));
443 this.changeHandlers.forEach((h) => h());
444 }
445
446 return result;

Callers 6

addElementMethod · 0.95
addGsapTweenMethod · 0.95
addWithKeyframesMethod · 0.95
replaceWithKeyframesMethod · 0.95
dispatchMethod · 0.95
commitPreviewMethod · 0.80

Calls 3

applyOpFunction · 0.85
pathToKeyFunction · 0.85
buildPatchEventFunction · 0.85

Tested by

no test coverage detected