@pixerate/editor 0.59.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/THIRD_PARTY_NOTICES.md +2 -0
  2. package/dist/agent/index.cjs +111 -38
  3. package/dist/agent/index.cjs.map +1 -1
  4. package/dist/agent/index.d.cts +30 -2
  5. package/dist/agent/index.d.ts +30 -2
  6. package/dist/agent/index.js +96 -23
  7. package/dist/agent/index.js.map +1 -1
  8. package/dist/agent-caret-BmYhQF7L.d.cts +106 -0
  9. package/dist/agent-caret-BmYhQF7L.d.ts +106 -0
  10. package/dist/animation-editor/index.cjs +197 -82
  11. package/dist/animation-editor/index.cjs.map +1 -1
  12. package/dist/animation-editor/index.d.cts +136 -3
  13. package/dist/animation-editor/index.d.ts +136 -3
  14. package/dist/animation-editor/index.js +163 -48
  15. package/dist/animation-editor/index.js.map +1 -1
  16. package/dist/{chunk-LMUDHBWR.js → chunk-4YFMSPBU.js} +2 -2
  17. package/dist/{chunk-3I6V7PI4.cjs → chunk-7ZSU4MQZ.cjs} +45 -45
  18. package/dist/{chunk-3I6V7PI4.cjs.map → chunk-7ZSU4MQZ.cjs.map} +1 -1
  19. package/dist/{chunk-WLVZ235X.js → chunk-OK7T2LHK.js} +229 -2
  20. package/dist/chunk-OK7T2LHK.js.map +1 -0
  21. package/dist/{chunk-AHCENCU4.cjs → chunk-T4XWVPJK.cjs} +253 -26
  22. package/dist/chunk-T4XWVPJK.cjs.map +1 -0
  23. package/dist/extensions/index.cjs +27 -3
  24. package/dist/extensions/index.cjs.map +1 -1
  25. package/dist/extensions/index.d.cts +2 -1
  26. package/dist/extensions/index.d.ts +2 -1
  27. package/dist/extensions/index.js +26 -2
  28. package/dist/{index-CTCc3m3C.d.ts → index-B16wbOn_.d.ts} +1 -0
  29. package/dist/{index-BcHyG0Wq.d.cts → index-BAt14aIU.d.cts} +1 -0
  30. package/dist/index.cjs +32 -8
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +3 -2
  33. package/dist/index.d.ts +3 -2
  34. package/dist/index.js +26 -2
  35. package/dist/index.js.map +1 -1
  36. package/package.json +1 -1
  37. package/dist/chunk-AHCENCU4.cjs.map +0 -1
  38. package/dist/chunk-WLVZ235X.js.map +0 -1
  39. /package/dist/{chunk-LMUDHBWR.js.map → chunk-4YFMSPBU.js.map} +0 -0
@@ -14,6 +14,10 @@ import {
14
14
  normalizeChartSpec
15
15
  } from "./chunk-633QC34G.js";
16
16
  import {
17
+ plainTextToSlice
18
+ } from "./chunk-UKI64KUD.js";
19
+ import {
20
+ TRACK_CHANGES_SKIP_META,
17
21
  isTrackChangesEnabled
18
22
  } from "./chunk-SWE3NPOU.js";
19
23
 
@@ -1999,6 +2003,217 @@ function createTableStore(editor) {
1999
2003
  };
2000
2004
  }
2001
2005
 
2006
+ // src/extensions/agent-caret.ts
2007
+ import { Extension } from "@tiptap/core";
2008
+ import { Plugin as Plugin3, PluginKey as PluginKey3 } from "@tiptap/pm/state";
2009
+ import { Decoration, DecorationSet } from "@tiptap/pm/view";
2010
+ var DEFAULT_AGENT_CARET_COLOR = "#8b5cf6";
2011
+ var DEFAULT_AGENT_CARET_NAME = "Agent";
2012
+ var agentCaretPluginKey = new PluginKey3("agentCaret");
2013
+ var clamp = (pos, size) => Math.max(0, Math.min(size, Math.round(pos)));
2014
+ function caretWidget(caret) {
2015
+ return (view) => {
2016
+ const doc = view.dom.ownerDocument;
2017
+ const el = doc.createElement("span");
2018
+ el.className = "pe-agent-caret";
2019
+ el.setAttribute("data-agent-id", caret.id);
2020
+ el.setAttribute("contenteditable", "false");
2021
+ el.setAttribute("aria-hidden", "true");
2022
+ el.style.cssText = `position:relative;margin-left:-1px;margin-right:-1px;border-left:2px solid ${caret.color};word-break:normal;pointer-events:none;`;
2023
+ const label = doc.createElement("span");
2024
+ label.className = "pe-agent-caret-label";
2025
+ label.textContent = caret.name;
2026
+ label.style.cssText = `position:absolute;left:-2px;bottom:100%;background:${caret.color};color:#fff;font:600 11px/1.5 system-ui,sans-serif;padding:0 5px;border-radius:3px 3px 3px 0;white-space:nowrap;user-select:none;pointer-events:none;`;
2027
+ el.append("\u2060", label, "\u2060");
2028
+ return el;
2029
+ };
2030
+ }
2031
+ var tint = (color, percent) => `color-mix(in srgb, ${color} ${percent}%, transparent)`;
2032
+ function buildDecorations(state, carets) {
2033
+ const decorations = [];
2034
+ for (const caret of carets) {
2035
+ for (const range of caret.changed) {
2036
+ decorations.push(
2037
+ Decoration.inline(range.from, range.to, {
2038
+ class: "pe-agent-changed",
2039
+ "data-agent-id": caret.id,
2040
+ style: `background-color:${tint(caret.color, 18)};`
2041
+ })
2042
+ );
2043
+ }
2044
+ const from = Math.min(caret.anchor, caret.head);
2045
+ const to = Math.max(caret.anchor, caret.head);
2046
+ if (from < to) {
2047
+ decorations.push(
2048
+ Decoration.inline(from, to, {
2049
+ class: "pe-agent-selection",
2050
+ "data-agent-id": caret.id,
2051
+ style: `background-color:${tint(caret.color, 28)};`
2052
+ })
2053
+ );
2054
+ }
2055
+ decorations.push(
2056
+ Decoration.widget(caret.head, caretWidget(caret), {
2057
+ key: `agent-caret:${caret.id}:${caret.name}:${caret.color}`,
2058
+ side: 10,
2059
+ ignoreSelection: true
2060
+ })
2061
+ );
2062
+ }
2063
+ return DecorationSet.create(state.doc, decorations);
2064
+ }
2065
+ function createAgentCaretPlugin() {
2066
+ return new Plugin3({
2067
+ key: agentCaretPluginKey,
2068
+ state: {
2069
+ init: (_, state) => ({ carets: [], spans: {}, decorations: DecorationSet.create(state.doc, []) }),
2070
+ apply(tr, value, _old, state) {
2071
+ const meta = tr.getMeta(agentCaretPluginKey);
2072
+ if (!tr.docChanged && !meta) return value;
2073
+ const size = state.doc.content.size;
2074
+ let carets = value.carets;
2075
+ let spans = value.spans;
2076
+ if (tr.docChanged) {
2077
+ const anchorBias = (c) => c.anchor <= c.head ? 1 : -1;
2078
+ carets = carets.map((c) => ({
2079
+ ...c,
2080
+ anchor: tr.mapping.map(c.anchor, anchorBias(c)),
2081
+ head: tr.mapping.map(c.head, -anchorBias(c)),
2082
+ changed: c.changed.map((r) => ({ from: tr.mapping.map(r.from, 1), to: tr.mapping.map(r.to, -1) })).filter((r) => r.from < r.to)
2083
+ }));
2084
+ const own = !!meta && "span" in meta;
2085
+ spans = Object.fromEntries(
2086
+ Object.entries(spans).map(([id, s]) => {
2087
+ const from = tr.mapping.map(s.from, 1);
2088
+ return [id, { from, to: Math.max(from, tr.mapping.map(s.to, -1)), foreign: s.foreign || !own }];
2089
+ })
2090
+ );
2091
+ }
2092
+ if (meta && "set" in meta) {
2093
+ const input = meta.set;
2094
+ const prev = carets.find((c) => c.id === input.id);
2095
+ const anchor = clamp(input.from, size);
2096
+ const caret = {
2097
+ id: input.id,
2098
+ name: input.name ?? prev?.name ?? DEFAULT_AGENT_CARET_NAME,
2099
+ color: input.color ?? prev?.color ?? DEFAULT_AGENT_CARET_COLOR,
2100
+ anchor,
2101
+ head: input.to === void 0 ? anchor : clamp(input.to, size),
2102
+ changed: prev?.changed ?? []
2103
+ };
2104
+ carets = prev ? carets.map((c) => c.id === input.id ? caret : c) : [...carets, caret];
2105
+ } else if (meta && "clear" in meta) {
2106
+ carets = meta.clear === null ? [] : carets.filter((c) => c.id !== meta.clear);
2107
+ } else if (meta && "changed" in meta) {
2108
+ const { id, ranges } = meta.changed;
2109
+ carets = carets.map(
2110
+ (c) => c.id === id ? { ...c, changed: ranges.map((r) => ({ from: clamp(r.from, size), to: clamp(r.to, size) })).filter((r) => r.from < r.to) } : c
2111
+ );
2112
+ } else if (meta && "span" in meta) {
2113
+ const span = meta.span;
2114
+ spans = { ...spans };
2115
+ if ("end" in span) delete spans[span.id];
2116
+ else spans[span.id] = { from: span.from, to: span.to, foreign: spans[span.id]?.foreign ?? false };
2117
+ }
2118
+ return { carets, spans, decorations: buildDecorations(state, carets) };
2119
+ }
2120
+ },
2121
+ props: {
2122
+ decorations: (state) => agentCaretPluginKey.getState(state)?.decorations
2123
+ }
2124
+ });
2125
+ }
2126
+ var AgentCaret = Extension.create({
2127
+ name: "agentCaret",
2128
+ addProseMirrorPlugins() {
2129
+ return [createAgentCaretPlugin()];
2130
+ }
2131
+ });
2132
+ function ensureAgentCaret(editor) {
2133
+ if (editor.isDestroyed || agentCaretPluginKey.getState(editor.state)) return;
2134
+ editor.registerPlugin(createAgentCaretPlugin());
2135
+ }
2136
+ function dispatchMeta(editor, meta) {
2137
+ if (editor.isDestroyed) return;
2138
+ ensureAgentCaret(editor);
2139
+ editor.view.dispatch(editor.state.tr.setMeta(agentCaretPluginKey, meta).setMeta("addToHistory", false));
2140
+ }
2141
+ function setAgentCaret(editor, caret) {
2142
+ dispatchMeta(editor, { set: caret });
2143
+ }
2144
+ function clearAgentCaret(editor, id) {
2145
+ if (editor.isDestroyed || !agentCaretPluginKey.getState(editor.state)) return;
2146
+ dispatchMeta(editor, { clear: id ?? null });
2147
+ }
2148
+ function markAgentChanges(editor, id, ranges) {
2149
+ if (!ranges.length && !agentCaretPluginKey.getState(editor.state)) return;
2150
+ dispatchMeta(editor, { changed: { id, ranges } });
2151
+ }
2152
+ function getAgentCarets(state) {
2153
+ return agentCaretPluginKey.getState(state)?.carets ?? [];
2154
+ }
2155
+ function replaceWithTextTransaction(state, from, to, text) {
2156
+ return /[\r\n]/.test(text) ? state.tr.replace(from, to, plainTextToSlice(text, state.schema)) : text ? state.tr.insertText(text, from, to) : state.tr.delete(from, to);
2157
+ }
2158
+ var NO_HISTORY = (tr) => tr.setMeta("addToHistory", false).setMeta(TRACK_CHANGES_SKIP_META, true);
2159
+ var cannotAnimate = () => typeof document === "undefined" || document.hidden === true;
2160
+ async function typeAgentText(editor, options) {
2161
+ const { from, to, text, caret, signal } = options;
2162
+ const cps = options.charsPerSecond ?? 60;
2163
+ const chars = Array.from(text);
2164
+ ensureAgentCaret(editor);
2165
+ const show = (tr, anchor, head = anchor) => tr.setMeta(agentCaretPluginKey, { set: { ...caret, from: anchor, to: head } });
2166
+ const commit = (start, end) => {
2167
+ const tr = replaceWithTextTransaction(editor.state, start, end, text);
2168
+ const insertedTo = tr.mapping.map(end, 1);
2169
+ const insertedFrom = Math.min(tr.mapping.map(start, -1), insertedTo);
2170
+ editor.view.dispatch(show(tr, insertedTo).scrollIntoView());
2171
+ if (insertedFrom < insertedTo) markAgentChanges(editor, caret.id, [{ from: insertedFrom, to: insertedTo }]);
2172
+ return { from: insertedFrom, to: insertedTo };
2173
+ };
2174
+ const animate = Number.isFinite(cps) && cps > 0 && chars.length > 0 && (options.wait || !cannotAnimate());
2175
+ if (!animate) return commit(from, to);
2176
+ const wait = options.wait ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
2177
+ const duration = Math.min(options.maxDurationMs ?? 1500, chars.length / cps * 1e3);
2178
+ const frameMs = 1e3 / 30;
2179
+ const frames = Math.max(1, Math.min(chars.length, Math.round(duration / frameMs)));
2180
+ const original = editor.state.doc.slice(from, to);
2181
+ const inverses = [];
2182
+ const span = () => agentCaretPluginKey.getState(editor.state).spans[caret.id];
2183
+ editor.view.dispatch(NO_HISTORY(editor.state.tr.setMeta(agentCaretPluginKey, { span: { id: caret.id, from, to } })));
2184
+ editor.view.dispatch(NO_HISTORY(show(editor.state.tr, from, to)));
2185
+ const rollback = () => {
2186
+ const s = span();
2187
+ const tr = editor.state.tr;
2188
+ if (!s.foreign) inverses.slice().reverse().forEach((step) => tr.step(step));
2189
+ else tr.replace(s.from, s.to, original);
2190
+ tr.setMeta(agentCaretPluginKey, { span: { id: caret.id, end: true } });
2191
+ editor.view.dispatch(NO_HISTORY(tr));
2192
+ return { from: s.from, to: s.from + original.size };
2193
+ };
2194
+ try {
2195
+ if (from < to) await wait(options.selectMs ?? 250);
2196
+ for (let i = 1; i <= frames; i++) {
2197
+ if (signal?.aborted) throw new Error("Typing was cancelled; the document is unchanged.");
2198
+ if (editor.isDestroyed) throw new Error("The editor was closed while the agent was typing.");
2199
+ const s = span();
2200
+ const prefix = chars.slice(0, Math.round(chars.length * i / frames)).join("");
2201
+ const tr = replaceWithTextTransaction(editor.state, s.from, s.to, prefix);
2202
+ tr.steps.forEach((step, k) => inverses.push(step.invert(tr.docs[k])));
2203
+ const end = tr.mapping.map(s.to, 1);
2204
+ tr.setMeta(agentCaretPluginKey, { span: { id: caret.id, from: Math.min(tr.mapping.map(s.from, -1), end), to: end } });
2205
+ editor.view.dispatch(NO_HISTORY(tr));
2206
+ editor.view.dispatch(NO_HISTORY(show(editor.state.tr, end)));
2207
+ if (i < frames) await wait(duration / frames);
2208
+ }
2209
+ } catch (error) {
2210
+ if (!editor.isDestroyed) rollback();
2211
+ throw error;
2212
+ }
2213
+ const restored = rollback();
2214
+ return commit(restored.from, restored.to);
2215
+ }
2216
+
2002
2217
  export {
2003
2218
  ALLOW_NESTED_TABLES_META,
2004
2219
  tableNestingPluginKey,
@@ -2057,6 +2272,18 @@ export {
2057
2272
  runTableAction,
2058
2273
  EMPTY_TABLE_STATE,
2059
2274
  getTableState,
2060
- createTableStore
2275
+ createTableStore,
2276
+ DEFAULT_AGENT_CARET_COLOR,
2277
+ DEFAULT_AGENT_CARET_NAME,
2278
+ agentCaretPluginKey,
2279
+ createAgentCaretPlugin,
2280
+ AgentCaret,
2281
+ ensureAgentCaret,
2282
+ setAgentCaret,
2283
+ clearAgentCaret,
2284
+ markAgentChanges,
2285
+ getAgentCarets,
2286
+ replaceWithTextTransaction,
2287
+ typeAgentText
2061
2288
  };
2062
- //# sourceMappingURL=chunk-WLVZ235X.js.map
2289
+ //# sourceMappingURL=chunk-OK7T2LHK.js.map