@vizejs/fresco 0.716.0 → 0.718.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 (50) hide show
  1. package/dist/{accessibility-OEhyYUxd.d.mts → accessibility-DwzT925M.d.mts} +46 -5
  2. package/dist/accessibility-DwzT925M.d.mts.map +1 -0
  3. package/dist/{app-CIX6NAW-.mjs → app-C_wFlWSV.mjs} +443 -123
  4. package/dist/app-C_wFlWSV.mjs.map +1 -0
  5. package/dist/app-_QmZ-PoH.d.mts +270 -0
  6. package/dist/app-_QmZ-PoH.d.mts.map +1 -0
  7. package/dist/ascii-font/index.d.mts +60 -0
  8. package/dist/ascii-font/index.d.mts.map +1 -0
  9. package/dist/ascii-font/index.mjs +68 -0
  10. package/dist/ascii-font/index.mjs.map +1 -0
  11. package/dist/components/index.d.mts +2 -2
  12. package/dist/components/index.mjs +2 -2
  13. package/dist/components-DzkL-yHj.mjs +6165 -0
  14. package/dist/components-DzkL-yHj.mjs.map +1 -0
  15. package/dist/composables/index.d.mts +3 -3
  16. package/dist/composables/index.mjs +4 -4
  17. package/dist/{composables-DbJGVNSG.mjs → composables-BJeirPSH.mjs} +116 -55
  18. package/dist/composables-BJeirPSH.mjs.map +1 -0
  19. package/dist/{index-CWRginDz.d.mts → index-B3zQ6E-5.d.mts} +1099 -337
  20. package/dist/index-B3zQ6E-5.d.mts.map +1 -0
  21. package/dist/{index-Dikou9bu.d.mts → index-Ddp2Txtm.d.mts} +52 -4
  22. package/dist/index-Ddp2Txtm.d.mts.map +1 -0
  23. package/dist/index.d.mts +98 -7
  24. package/dist/index.d.mts.map +1 -0
  25. package/dist/index.mjs +262 -5
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/{protocol-D8xt3DG7.d.mts → protocol-DavoeNLn.d.mts} +14 -4
  28. package/dist/{protocol-D8xt3DG7.d.mts.map → protocol-DavoeNLn.d.mts.map} +1 -1
  29. package/dist/qr-code/index.d.mts +101 -0
  30. package/dist/qr-code/index.d.mts.map +1 -0
  31. package/dist/qr-code/index.mjs +88 -0
  32. package/dist/qr-code/index.mjs.map +1 -0
  33. package/dist/testing/index.d.mts +3 -3
  34. package/dist/testing/index.mjs +1 -1
  35. package/dist/{useApp-CVB2jNCO.d.mts → useApp-vIRJ5Th3.d.mts} +34 -8
  36. package/dist/useApp-vIRJ5Th3.d.mts.map +1 -0
  37. package/dist/{useVirtualViewport-pPZWmwUC.mjs → useBoxMetrics-lF5Myjc7.mjs} +66 -6
  38. package/dist/useBoxMetrics-lF5Myjc7.mjs.map +1 -0
  39. package/package.json +14 -6
  40. package/dist/accessibility-OEhyYUxd.d.mts.map +0 -1
  41. package/dist/app-CIX6NAW-.mjs.map +0 -1
  42. package/dist/app-CKsTWQuP.d.mts +0 -154
  43. package/dist/app-CKsTWQuP.d.mts.map +0 -1
  44. package/dist/components-D9SeB0Be.mjs +0 -3331
  45. package/dist/components-D9SeB0Be.mjs.map +0 -1
  46. package/dist/composables-DbJGVNSG.mjs.map +0 -1
  47. package/dist/index-CWRginDz.d.mts.map +0 -1
  48. package/dist/index-Dikou9bu.d.mts.map +0 -1
  49. package/dist/useApp-CVB2jNCO.d.mts.map +0 -1
  50. package/dist/useVirtualViewport-pPZWmwUC.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
1
  import { a as createVirtualViewport, i as VirtualViewportRange, n as VirtualViewport, o as useVirtualViewport, r as VirtualViewportOptions, t as VirtualScrollAlignment } from "../useVirtualViewport-TxTapifg.mjs";
2
- import { A as KeyHandler, C as UseMouseOptions, D as usePaste, E as UsePasteOptions, M as UseInputReturn, N as useInput, O as InputHandler, P as useKeyPress, S as useIme, T as useMouse, _ as useStderr, b as ImeManager, c as UseAnimationOptions, d as useCursor, f as WindowSize, g as UseStdoutReturn, h as UseStdinReturn, i as useBoxMetrics, j as UseInputOptions, k as Key, l as useAnimation, m as UseStderrReturn, n as BoxMetrics, p as useWindowSize, r as UseBoxMetricsResult, s as AnimationResult, t as useIsScreenReaderEnabled, u as CursorPosition, v as useStdin, w as UseMouseReturn, x as UseImeOptions, y as useStdout } from "../index-Dikou9bu.mjs";
3
- import { a as useFocus, i as UseFocusOptions, n as useApp, o as useFocusManager, r as FocusManager, t as UseAppReturn } from "../useApp-CVB2jNCO.mjs";
4
- export { type AnimationResult, type BoxMetrics, type CursorPosition, type FocusManager, type ImeManager, type InputHandler, type Key, type KeyHandler, type UseAnimationOptions, type UseAppReturn, type UseBoxMetricsResult, type UseFocusOptions, type UseImeOptions, type UseInputOptions, type UseInputReturn, type UseMouseOptions, type UseMouseReturn, type UsePasteOptions, type UseStderrReturn, type UseStdinReturn, type UseStdoutReturn, type VirtualScrollAlignment, type VirtualViewport, type VirtualViewportOptions, type VirtualViewportRange, type WindowSize, createVirtualViewport, useAnimation, useApp, useBoxMetrics, useCursor, useFocus, useFocusManager, useIme, useInput, useIsScreenReaderEnabled, useKeyPress, useMouse, usePaste, useStderr, useStdin, useStdout, useVirtualViewport, useWindowSize };
2
+ import { A as ImeManager, B as KeyHandler, C as useWindowSize, D as useStderr, E as UseStdoutReturn, F as useMouse, H as UseInputReturn, I as UsePasteOptions, L as usePaste, M as useIme, N as UseMouseOptions, O as useStdin, P as UseMouseReturn, R as InputHandler, S as WindowSize, T as UseStdinReturn, U as useInput, V as UseInputOptions, W as useKeyPress, _ as AnimationResult, a as KeymapStroke, b as CursorPosition, c as createKeymapResolver, d as useIsScreenReaderEnabled, f as BoxMetrics, i as KeymapResolver, j as UseImeOptions, k as useStdout, l as defineKeymap, m as useBoxMetrics, n as KeymapBinding, o as UseKeymapOptions, p as UseBoxMetricsResult, r as KeymapMatch, s as UseKeymapReturn, t as Keymap, u as useKeymap, v as UseAnimationOptions, w as UseStderrReturn, x as useCursor, y as useAnimation, z as Key } from "../index-Ddp2Txtm.mjs";
3
+ import { a as provideFocusScope, i as UseFocusOptions, n as useApp, o as useFocus, r as FocusManager, s as useFocusManager, t as UseAppReturn } from "../useApp-vIRJ5Th3.mjs";
4
+ export { type AnimationResult, type BoxMetrics, type CursorPosition, type FocusManager, type ImeManager, type InputHandler, type Key, type KeyHandler, type Keymap, type KeymapBinding, type KeymapMatch, type KeymapResolver, type KeymapStroke, type UseAnimationOptions, type UseAppReturn, type UseBoxMetricsResult, type UseFocusOptions, type UseImeOptions, type UseInputOptions, type UseInputReturn, type UseKeymapOptions, type UseKeymapReturn, type UseMouseOptions, type UseMouseReturn, type UsePasteOptions, type UseStderrReturn, type UseStdinReturn, type UseStdoutReturn, type VirtualScrollAlignment, type VirtualViewport, type VirtualViewportOptions, type VirtualViewportRange, type WindowSize, createKeymapResolver, createVirtualViewport, defineKeymap, provideFocusScope, useAnimation, useApp, useBoxMetrics, useCursor, useFocus, useFocusManager, useIme, useInput, useIsScreenReaderEnabled, useKeyPress, useKeymap, useMouse, usePaste, useStderr, useStdin, useStdout, useVirtualViewport, useWindowSize };
@@ -1,4 +1,4 @@
1
- import { C as useStdin, M as useApp, O as useFocus, S as useStderr, k as useFocusManager, w as useStdout, y as useCursor } from "../app-CIX6NAW-.mjs";
2
- import { a as useKeyPress, i as useInput, n as useVirtualViewport, o as usePaste, r as useMouse, s as useIsScreenReaderEnabled, t as createVirtualViewport } from "../useVirtualViewport-pPZWmwUC.mjs";
3
- import { i as useIme, n as useAnimation, r as useWindowSize, t as useBoxMetrics } from "../composables-DbJGVNSG.mjs";
4
- export { createVirtualViewport, useAnimation, useApp, useBoxMetrics, useCursor, useFocus, useFocusManager, useIme, useInput, useIsScreenReaderEnabled, useKeyPress, useMouse, usePaste, useStderr, useStdin, useStdout, useVirtualViewport, useWindowSize };
1
+ import { A as useFocusManager, C as useStdin, N as useApp, O as provideFocusScope, S as useStderr, k as useFocus, w as useStdout, y as useCursor } from "../app-C_wFlWSV.mjs";
2
+ import { a as useInput, c as useIsScreenReaderEnabled, i as useMouse, n as createVirtualViewport, o as useKeyPress, r as useVirtualViewport, s as usePaste, t as useBoxMetrics } from "../useBoxMetrics-lF5Myjc7.mjs";
3
+ import { a as useWindowSize, i as useAnimation, n as defineKeymap, o as useIme, r as useKeymap, t as createKeymapResolver } from "../composables-BJeirPSH.mjs";
4
+ export { createKeymapResolver, createVirtualViewport, defineKeymap, provideFocusScope, useAnimation, useApp, useBoxMetrics, useCursor, useFocus, useFocusManager, useIme, useInput, useIsScreenReaderEnabled, useKeyPress, useKeymap, useMouse, usePaste, useStderr, useStdin, useStdout, useVirtualViewport, useWindowSize };
@@ -1,6 +1,6 @@
1
- import { M as useApp, g as updateLastRenderLayouts, m as getLastRenderLayout } from "./app-CIX6NAW-.mjs";
2
- import "./useVirtualViewport-pPZWmwUC.mjs";
3
- import { computed, onMounted, onUnmounted, reactive, ref, watch } from "vue";
1
+ import { N as useApp } from "./app-C_wFlWSV.mjs";
2
+ import { a as useInput } from "./useBoxMetrics-lF5Myjc7.mjs";
3
+ import { computed, onMounted, onUnmounted, reactive, readonly, ref, toValue, watch } from "vue";
4
4
  //#region src/composables/useIme.ts
5
5
  /**
6
6
  * useIme - IME (Input Method Editor) composable
@@ -255,65 +255,126 @@ function useAnimation(options = {}) {
255
255
  return state;
256
256
  }
257
257
  //#endregion
258
- //#region src/composables/useBoxMetrics.ts
259
- /**
260
- * useBoxMetrics - best-effort layout metrics for a rendered Fresco node.
261
- */
262
- async function loadNative() {
263
- return import("@vizejs/fresco-native");
258
+ //#region src/composables/useKeymap.ts
259
+ function normalizedKey(key) {
260
+ const lower = key.toLowerCase();
261
+ if (lower === "return") return "enter";
262
+ if (lower === "esc") return "escape";
263
+ if (lower === "pagedown") return "pagedown";
264
+ if (lower === "pageup") return "pageup";
265
+ return lower;
266
+ }
267
+ function normalizedStroke(stroke) {
268
+ return {
269
+ key: normalizedKey(stroke.key),
270
+ ctrl: stroke.ctrl ?? false,
271
+ alt: stroke.alt ?? false,
272
+ shift: stroke.shift ?? false,
273
+ meta: stroke.meta ?? false
274
+ };
264
275
  }
265
- function targetId(target) {
266
- return target?.id ?? target?.$el?.id;
276
+ function strokesEqual(left, right) {
277
+ const normalizedLeft = normalizedStroke(left);
278
+ const normalizedRight = normalizedStroke(right);
279
+ return normalizedLeft.key === normalizedRight.key && normalizedLeft.ctrl === normalizedRight.ctrl && normalizedLeft.alt === normalizedRight.alt && normalizedLeft.shift === normalizedRight.shift && normalizedLeft.meta === normalizedRight.meta;
267
280
  }
268
- function useBoxMetrics(ref) {
269
- const metrics = reactive({
270
- width: 0,
271
- height: 0,
272
- left: 0,
273
- top: 0,
274
- hasMeasured: false
281
+ function sequenceKey(sequence) {
282
+ return sequence.map((stroke) => {
283
+ const normalized = normalizedStroke(stroke);
284
+ return [
285
+ normalized.ctrl ? "ctrl" : "",
286
+ normalized.alt ? "alt" : "",
287
+ normalized.shift ? "shift" : "",
288
+ normalized.meta ? "meta" : "",
289
+ normalized.key
290
+ ].filter(Boolean).join("+");
291
+ }).join(" ");
292
+ }
293
+ /** Validate and freeze a typed command map. */
294
+ function defineKeymap(bindings) {
295
+ const seen = /* @__PURE__ */ new Set();
296
+ const normalized = bindings.map((binding) => {
297
+ if (binding.sequence.length === 0) throw new TypeError("keymap sequences must not be empty");
298
+ const sequence = binding.sequence.map(normalizedStroke);
299
+ const key = sequenceKey(sequence);
300
+ if (seen.has(key)) throw new TypeError(`duplicate keymap sequence: ${key}`);
301
+ seen.add(key);
302
+ return Object.freeze({
303
+ command: binding.command,
304
+ sequence: Object.freeze(sequence)
305
+ });
275
306
  });
276
- let timer = null;
277
- const refresh = () => {
278
- const id = targetId(ref.value);
279
- if (id === void 0) {
280
- metrics.width = 0;
281
- metrics.height = 0;
282
- metrics.left = 0;
283
- metrics.top = 0;
284
- metrics.hasMeasured = false;
285
- return;
307
+ return Object.freeze(normalized);
308
+ }
309
+ /** Stateful matcher for single chords, Emacs multi-chords, and Vim-style sequences. */
310
+ function createKeymapResolver(keymap) {
311
+ let pending = [];
312
+ const matchingBindings = (sequence) => keymap().filter((binding) => binding.sequence.length >= sequence.length && sequence.every((stroke, index) => strokesEqual(stroke, binding.sequence[index])));
313
+ const feed = (stroke) => {
314
+ const next = [...pending, normalizedStroke(stroke)];
315
+ let matches = matchingBindings(next);
316
+ let candidate = next;
317
+ if (matches.length === 0 && pending.length > 0) {
318
+ candidate = [normalizedStroke(stroke)];
319
+ matches = matchingBindings(candidate);
320
+ }
321
+ const exact = matches.find((binding) => binding.sequence.length === candidate.length);
322
+ if (exact) {
323
+ pending = [];
324
+ return {
325
+ command: exact.command,
326
+ binding: exact,
327
+ pending: false
328
+ };
286
329
  }
287
- loadNative().then((native) => {
288
- const layouts = "getLastRenderLayouts" in native ? native.getLastRenderLayouts() : [];
289
- updateLastRenderLayouts(layouts);
290
- const layout = layouts.find((item) => item.id === id);
291
- if (!layout) return;
292
- metrics.width = layout.width;
293
- metrics.height = layout.height;
294
- metrics.left = layout.x;
295
- metrics.top = layout.y;
296
- metrics.hasMeasured = true;
297
- }).catch(() => {});
330
+ pending = matches.length > 0 ? candidate : [];
331
+ return { pending: pending.length > 0 };
298
332
  };
299
- onMounted(() => {
300
- const layout = getLastRenderLayout(ref.value);
301
- if (layout) {
302
- metrics.width = layout.width;
303
- metrics.height = layout.height;
304
- metrics.left = layout.x;
305
- metrics.top = layout.y;
306
- metrics.hasMeasured = true;
333
+ return {
334
+ get pendingSequence() {
335
+ return pending;
336
+ },
337
+ feed,
338
+ reset: () => {
339
+ pending = [];
340
+ }
341
+ };
342
+ }
343
+ /** Subscribe a typed command keymap to Fresco's normalized input stream. */
344
+ function useKeymap(options) {
345
+ const active = computed(() => toValue(options.active) ?? true);
346
+ const resolver = createKeymapResolver(() => toValue(options.keymap));
347
+ const pendingSequence = ref([]);
348
+ const timeout = Math.max(0, options.sequenceTimeout ?? 1e3);
349
+ let timer;
350
+ const reset = () => {
351
+ if (timer !== void 0) clearTimeout(timer);
352
+ timer = void 0;
353
+ resolver.reset();
354
+ pendingSequence.value = [];
355
+ };
356
+ watch(() => toValue(options.keymap), () => reset());
357
+ onUnmounted(reset);
358
+ useInput({
359
+ isActive: active,
360
+ onKey: (key, modifiers) => {
361
+ if (timer !== void 0) clearTimeout(timer);
362
+ const match = resolver.feed({
363
+ key,
364
+ ...modifiers
365
+ });
366
+ pendingSequence.value = [...resolver.pendingSequence];
367
+ if (match.command !== void 0 && match.binding !== void 0) options.onCommand(match.command, match.binding);
368
+ else if (match.pending && timeout > 0) timer = setTimeout(reset, timeout);
307
369
  }
308
- refresh();
309
- timer = setInterval(refresh, 100);
310
- });
311
- onUnmounted(() => {
312
- if (timer) clearInterval(timer);
313
370
  });
314
- return metrics;
371
+ return {
372
+ isActive: active,
373
+ pendingSequence: readonly(pendingSequence),
374
+ reset
375
+ };
315
376
  }
316
377
  //#endregion
317
- export { useIme as i, useAnimation as n, useWindowSize as r, useBoxMetrics as t };
378
+ export { useWindowSize as a, useAnimation as i, defineKeymap as n, useIme as o, useKeymap as r, createKeymapResolver as t };
318
379
 
319
- //# sourceMappingURL=composables-DbJGVNSG.mjs.map
380
+ //# sourceMappingURL=composables-BJeirPSH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composables-BJeirPSH.mjs","names":[],"sources":["../src/composables/useIme.ts","../src/composables/useWindowSize.ts","../src/composables/useAnimation.ts","../src/composables/useKeymap.ts"],"sourcesContent":["/**\n * useIme - IME (Input Method Editor) composable\n */\n\nimport { ref, computed, type Ref } from \"vue\";\n\nexport interface UseImeOptions {\n /** Initial IME mode */\n mode?: ImeMode;\n /** Called when IME mode changes */\n onModeChange?: (mode: ImeMode) => void;\n /** Called when composition updates */\n onCompositionUpdate?: (text: string, cursor: number) => void;\n /** Called when text is committed */\n onCommit?: (text: string) => void;\n}\n\nexport type ImeMode =\n | \"direct\"\n | \"hiragana\"\n | \"katakana\"\n | \"half-katakana\"\n | \"full-alpha\"\n | \"pinyin\"\n | \"hangul\";\n\nexport interface ImeManager {\n /** Whether IME is active */\n isActive: Ref<boolean>;\n /** Current input mode */\n mode: Ref<ImeMode>;\n /** Whether currently composing */\n isComposing: Ref<boolean>;\n /** Preedit text */\n preedit: Ref<string>;\n /** Cursor position in preedit */\n preeditCursor: Ref<number>;\n /** Candidate list */\n candidates: Ref<string[]>;\n /** Selected candidate index */\n selectedCandidate: Ref<number>;\n /** Mode display name */\n modeDisplay: Ref<string>;\n /** Enable IME */\n enable: () => void;\n /** Disable IME */\n disable: () => void;\n /** Set input mode */\n setMode: (mode: ImeMode) => void;\n /** Handle key event for IME */\n handleKey: (key: string, modifiers: { ctrl: boolean; alt: boolean }) => boolean;\n /** Commit current composition */\n commit: () => void;\n /** Cancel current composition */\n cancel: () => void;\n /** Select next candidate */\n nextCandidate: () => void;\n /** Select previous candidate */\n prevCandidate: () => void;\n /** Select candidate by number (1-9) */\n selectCandidate: (num: number) => void;\n}\n\nconst MODE_DISPLAY: Record<ImeMode, string> = {\n direct: \"A\",\n hiragana: \"あ\",\n katakana: \"ア\",\n \"half-katakana\": \"ア\",\n \"full-alpha\": \"A\",\n pinyin: \"拼\",\n hangul: \"한\",\n};\n\nexport function useIme(options: UseImeOptions = {}): ImeManager {\n const { mode: initialMode = \"direct\", onModeChange, onCompositionUpdate, onCommit } = options;\n\n const isActive = ref(false);\n const mode = ref<ImeMode>(initialMode);\n const isComposing = ref(false);\n const preedit = ref(\"\");\n const preeditCursor = ref(0);\n const candidates = ref<string[]>([]);\n const selectedCandidate = ref(0);\n\n const modeDisplay = computed(() => MODE_DISPLAY[mode.value] ?? \"A\");\n\n const enable = () => {\n isActive.value = true;\n };\n\n const disable = () => {\n isActive.value = false;\n cancel();\n };\n\n const setMode = (newMode: ImeMode) => {\n if (mode.value !== newMode) {\n cancel();\n mode.value = newMode;\n onModeChange?.(newMode);\n }\n };\n\n const handleKey = (key: string, modifiers: { ctrl: boolean; alt: boolean }): boolean => {\n if (!isActive.value || mode.value === \"direct\") {\n return false;\n }\n\n // IME mode toggle (usually Ctrl+Space or similar)\n // If we're here, mode is not 'direct' (filtered above), so toggle to 'direct'\n if (modifiers.ctrl && key === \" \") {\n setMode(\"direct\");\n return true;\n }\n\n // Handle composition\n if (isComposing.value) {\n switch (key) {\n case \"enter\":\n commit();\n return true;\n case \"escape\":\n cancel();\n return true;\n case \"backspace\":\n if (preedit.value.length > 0) {\n preedit.value = preedit.value.slice(0, -1);\n preeditCursor.value = Math.min(preeditCursor.value, preedit.value.length);\n onCompositionUpdate?.(preedit.value, preeditCursor.value);\n return true;\n }\n break;\n case \"space\":\n // Convert / select candidate\n if (candidates.value.length > 0) {\n nextCandidate();\n return true;\n }\n break;\n }\n\n // Number for candidate selection\n if (/^[1-9]$/.test(key)) {\n selectCandidate(parseInt(key, 10));\n return true;\n }\n }\n\n // Start/continue composition for printable characters\n if (key.length === 1 && !modifiers.ctrl && !modifiers.alt) {\n if (!isComposing.value) {\n isComposing.value = true;\n }\n preedit.value += key;\n preeditCursor.value = preedit.value.length;\n onCompositionUpdate?.(preedit.value, preeditCursor.value);\n return true;\n }\n\n return false;\n };\n\n const commit = () => {\n if (preedit.value) {\n const text = candidates.value[selectedCandidate.value] ?? preedit.value;\n onCommit?.(text);\n }\n preedit.value = \"\";\n preeditCursor.value = 0;\n candidates.value = [];\n selectedCandidate.value = 0;\n isComposing.value = false;\n };\n\n const cancel = () => {\n preedit.value = \"\";\n preeditCursor.value = 0;\n candidates.value = [];\n selectedCandidate.value = 0;\n isComposing.value = false;\n };\n\n const nextCandidate = () => {\n if (candidates.value.length > 0) {\n selectedCandidate.value = (selectedCandidate.value + 1) % candidates.value.length;\n }\n };\n\n const prevCandidate = () => {\n if (candidates.value.length > 0) {\n selectedCandidate.value =\n (selectedCandidate.value - 1 + candidates.value.length) % candidates.value.length;\n }\n };\n\n const selectCandidate = (num: number) => {\n if (num >= 1 && num <= candidates.value.length) {\n selectedCandidate.value = num - 1;\n commit();\n }\n };\n\n return {\n isActive,\n mode,\n isComposing,\n preedit,\n preeditCursor,\n candidates,\n selectedCandidate,\n modeDisplay,\n enable,\n disable,\n setMode,\n handleKey,\n commit,\n cancel,\n nextCandidate,\n prevCandidate,\n selectCandidate,\n };\n}\n","/**\n * useWindowSize - terminal dimensions.\n */\n\nimport { reactive } from \"vue\";\nimport { useApp } from \"./useApp.js\";\n\nexport interface WindowSize {\n columns: number;\n rows: number;\n}\n\nexport function useWindowSize() {\n const { width, height } = useApp();\n\n return reactive({\n get columns() {\n return width.value;\n },\n get rows() {\n return height.value;\n },\n }) as WindowSize;\n}\n","/**\n * useAnimation - Ink-compatible shared animation state.\n */\n\nimport { computed, onMounted, onUnmounted, reactive, watch } from \"vue\";\n\nexport interface UseAnimationOptions {\n /** Time between ticks in milliseconds */\n interval?: number;\n /** Whether the animation is running */\n isActive?: boolean;\n}\n\nexport interface AnimationResult {\n frame: number;\n time: number;\n delta: number;\n reset: () => void;\n}\n\nconst defaultAnimationInterval = 100;\nconst maximumTimerInterval = 2_147_483_647;\n\ntype AnimationCallback = (currentTime: number) => void;\n\ninterface AnimationSubscriber {\n callback: AnimationCallback;\n interval: number;\n startTime: number;\n nextDueTime: number;\n}\n\nconst animationSubscribers = new Map<AnimationCallback, AnimationSubscriber>();\nlet animationTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction currentTime(): number {\n return performance.now();\n}\n\nfunction normalizeAnimationInterval(interval: number): number {\n if (!Number.isFinite(interval)) {\n return defaultAnimationInterval;\n }\n\n return Math.min(maximumTimerInterval, Math.max(1, interval));\n}\n\nfunction clearAnimationTimer() {\n if (!animationTimer) return;\n clearTimeout(animationTimer);\n animationTimer = null;\n}\n\nfunction scheduleAnimationTick() {\n clearAnimationTimer();\n if (animationSubscribers.size === 0) return;\n\n let nextDueTime = Number.POSITIVE_INFINITY;\n for (const subscriber of animationSubscribers.values()) {\n nextDueTime = Math.min(nextDueTime, subscriber.nextDueTime);\n }\n\n animationTimer = setTimeout(\n () => {\n animationTimer = null;\n const now = currentTime();\n\n for (const subscriber of animationSubscribers.values()) {\n if (now < subscriber.nextDueTime) continue;\n\n subscriber.callback(now);\n\n const elapsedTime = now - subscriber.startTime;\n const elapsedFrames = Math.floor(elapsedTime / subscriber.interval) + 1;\n subscriber.nextDueTime = subscriber.startTime + elapsedFrames * subscriber.interval;\n }\n\n scheduleAnimationTick();\n },\n Math.max(0, nextDueTime - currentTime()),\n );\n}\n\nfunction subscribeToAnimation(callback: AnimationCallback, interval: number) {\n const startTime = currentTime();\n animationSubscribers.set(callback, {\n callback,\n interval,\n startTime,\n nextDueTime: startTime + interval,\n });\n scheduleAnimationTick();\n\n return {\n startTime,\n unsubscribe() {\n animationSubscribers.delete(callback);\n scheduleAnimationTick();\n },\n };\n}\n\nexport function useAnimation(options: UseAnimationOptions = {}): AnimationResult {\n const safeInterval = computed(() =>\n normalizeAnimationInterval(options.interval ?? defaultAnimationInterval),\n );\n const active = computed(() => options.isActive ?? true);\n let unsubscribe: (() => void) | null = null;\n let startedAt = currentTime();\n let previousTick = startedAt;\n\n const state = reactive<AnimationResult>({\n frame: 0,\n time: 0,\n delta: 0,\n reset: () => {\n if (active.value) {\n start();\n } else {\n resetState(currentTime());\n }\n },\n });\n\n const resetState = (now: number) => {\n startedAt = now;\n previousTick = now;\n state.frame = 0;\n state.time = 0;\n state.delta = 0;\n };\n\n const tick = (now: number) => {\n const elapsed = now - startedAt;\n state.frame = Math.floor(elapsed / safeInterval.value);\n state.time = elapsed;\n state.delta = now - previousTick;\n previousTick = now;\n };\n\n const stop = () => {\n unsubscribe?.();\n unsubscribe = null;\n };\n\n const start = () => {\n stop();\n resetState(currentTime());\n const subscription = subscribeToAnimation(tick, safeInterval.value);\n startedAt = subscription.startTime;\n previousTick = subscription.startTime;\n unsubscribe = () => subscription.unsubscribe();\n };\n\n onMounted(() => {\n if (active.value) {\n start();\n }\n });\n\n watch([active, safeInterval], ([isActive]) => {\n if (isActive) {\n start();\n } else {\n stop();\n }\n });\n\n onUnmounted(stop);\n\n return state;\n}\n","import {\n computed,\n onUnmounted,\n readonly,\n ref,\n toValue,\n watch,\n type MaybeRefOrGetter,\n type Ref,\n} from \"vue\";\nimport { useInput } from \"./useInput.js\";\n\nexport interface KeymapStroke {\n readonly key: string;\n readonly ctrl?: boolean;\n readonly alt?: boolean;\n readonly shift?: boolean;\n readonly meta?: boolean;\n}\n\nexport interface KeymapBinding<Command extends string = string> {\n readonly command: Command;\n readonly sequence: readonly [KeymapStroke, ...KeymapStroke[]];\n}\n\nexport type Keymap<Command extends string = string> = readonly KeymapBinding<Command>[];\n\nexport interface KeymapMatch<Command extends string> {\n readonly command?: Command;\n readonly binding?: KeymapBinding<Command>;\n readonly pending: boolean;\n}\n\nexport interface KeymapResolver<Command extends string> {\n readonly pendingSequence: readonly KeymapStroke[];\n feed(stroke: KeymapStroke): KeymapMatch<Command>;\n reset(): void;\n}\n\nexport interface UseKeymapOptions<Command extends string> {\n readonly keymap: MaybeRefOrGetter<Keymap<Command>>;\n readonly active?: MaybeRefOrGetter<boolean>;\n /** Idle time before an incomplete multi-stroke sequence is cleared. */\n readonly sequenceTimeout?: number;\n readonly onCommand: (command: Command, binding: KeymapBinding<Command>) => void;\n}\n\nexport interface UseKeymapReturn {\n readonly isActive: Readonly<Ref<boolean>>;\n readonly pendingSequence: Readonly<Ref<readonly KeymapStroke[]>>;\n reset(): void;\n}\n\nfunction normalizedKey(key: string): string {\n const lower = key.toLowerCase();\n if (lower === \"return\") return \"enter\";\n if (lower === \"esc\") return \"escape\";\n if (lower === \"pagedown\") return \"pagedown\";\n if (lower === \"pageup\") return \"pageup\";\n return lower;\n}\n\nfunction normalizedStroke(stroke: KeymapStroke): Required<KeymapStroke> {\n return {\n key: normalizedKey(stroke.key),\n ctrl: stroke.ctrl ?? false,\n alt: stroke.alt ?? false,\n shift: stroke.shift ?? false,\n meta: stroke.meta ?? false,\n };\n}\n\nfunction strokesEqual(left: KeymapStroke, right: KeymapStroke): boolean {\n const normalizedLeft = normalizedStroke(left);\n const normalizedRight = normalizedStroke(right);\n return (\n normalizedLeft.key === normalizedRight.key &&\n normalizedLeft.ctrl === normalizedRight.ctrl &&\n normalizedLeft.alt === normalizedRight.alt &&\n normalizedLeft.shift === normalizedRight.shift &&\n normalizedLeft.meta === normalizedRight.meta\n );\n}\n\nfunction sequenceKey(sequence: readonly KeymapStroke[]): string {\n return sequence\n .map((stroke) => {\n const normalized = normalizedStroke(stroke);\n return [\n normalized.ctrl ? \"ctrl\" : \"\",\n normalized.alt ? \"alt\" : \"\",\n normalized.shift ? \"shift\" : \"\",\n normalized.meta ? \"meta\" : \"\",\n normalized.key,\n ]\n .filter(Boolean)\n .join(\"+\");\n })\n .join(\" \");\n}\n\n/** Validate and freeze a typed command map. */\nexport function defineKeymap<const Command extends string>(\n bindings: readonly KeymapBinding<Command>[],\n): Keymap<Command> {\n const seen = new Set<string>();\n const normalized = bindings.map((binding) => {\n if (binding.sequence.length === 0) throw new TypeError(\"keymap sequences must not be empty\");\n const sequence = binding.sequence.map(normalizedStroke) as [\n Required<KeymapStroke>,\n ...Required<KeymapStroke>[],\n ];\n const key = sequenceKey(sequence);\n if (seen.has(key)) throw new TypeError(`duplicate keymap sequence: ${key}`);\n seen.add(key);\n return Object.freeze({ command: binding.command, sequence: Object.freeze(sequence) });\n });\n return Object.freeze(normalized);\n}\n\n/** Stateful matcher for single chords, Emacs multi-chords, and Vim-style sequences. */\nexport function createKeymapResolver<Command extends string>(\n keymap: () => Keymap<Command>,\n): KeymapResolver<Command> {\n let pending: KeymapStroke[] = [];\n\n const matchingBindings = (sequence: readonly KeymapStroke[]) =>\n keymap().filter(\n (binding) =>\n binding.sequence.length >= sequence.length &&\n sequence.every((stroke, index) => strokesEqual(stroke, binding.sequence[index]!)),\n );\n\n const feed = (stroke: KeymapStroke): KeymapMatch<Command> => {\n const next = [...pending, normalizedStroke(stroke)];\n let matches = matchingBindings(next);\n let candidate = next;\n if (matches.length === 0 && pending.length > 0) {\n candidate = [normalizedStroke(stroke)];\n matches = matchingBindings(candidate);\n }\n const exact = matches.find((binding) => binding.sequence.length === candidate.length);\n if (exact) {\n pending = [];\n return { command: exact.command, binding: exact, pending: false };\n }\n pending = matches.length > 0 ? candidate : [];\n return { pending: pending.length > 0 };\n };\n\n return {\n get pendingSequence() {\n return pending;\n },\n feed,\n reset: () => {\n pending = [];\n },\n };\n}\n\n/** Subscribe a typed command keymap to Fresco's normalized input stream. */\nexport function useKeymap<Command extends string>(\n options: UseKeymapOptions<Command>,\n): UseKeymapReturn {\n const active = computed(() => toValue(options.active) ?? true);\n const resolver = createKeymapResolver(() => toValue(options.keymap));\n const pendingSequence = ref<readonly KeymapStroke[]>([]);\n const timeout = Math.max(0, options.sequenceTimeout ?? 1_000);\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const reset = () => {\n if (timer !== undefined) clearTimeout(timer);\n timer = undefined;\n resolver.reset();\n pendingSequence.value = [];\n };\n\n watch(\n () => toValue(options.keymap),\n () => reset(),\n );\n onUnmounted(reset);\n\n useInput({\n isActive: active,\n onKey: (key, modifiers) => {\n if (timer !== undefined) clearTimeout(timer);\n const match = resolver.feed({ key, ...modifiers });\n pendingSequence.value = [...resolver.pendingSequence];\n if (match.command !== undefined && match.binding !== undefined) {\n options.onCommand(match.command, match.binding);\n } else if (match.pending && timeout > 0) {\n timer = setTimeout(reset, timeout);\n }\n },\n });\n\n return { isActive: active, pendingSequence: readonly(pendingSequence), reset };\n}\n"],"mappings":"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"}