@opentui/core 0.5.8 → 0.5.10

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.
package/edit-buffer.d.ts CHANGED
@@ -46,6 +46,8 @@ export declare class EditBuffer extends EventEmitter {
46
46
  */
47
47
  replaceTextOwned(text: string): void;
48
48
  getLineCount(): number;
49
+ setTabWidth(width: number): void;
50
+ getTabWidth(): number;
49
51
  getText(): string;
50
52
  insertChar(char: string): void;
51
53
  insertText(text: string): void;
package/image.d.ts CHANGED
@@ -62,10 +62,16 @@ export interface RawImage {
62
62
  colorSpace: "srgb";
63
63
  alpha: "straight";
64
64
  }
65
+ export interface PixelImportOptions {
66
+ stride?: number;
67
+ format?: PixelFormat;
68
+ alpha?: "straight" | "opaque";
69
+ colorSpace?: "srgb";
70
+ }
65
71
  export interface OwnedRawImage extends RawImage {
66
72
  dispose(): void;
67
73
  }
68
- export type ImageErrorCode = "invalid-handle" | "unsupported-format" | "unsupported-color-space" | "malformed-data" | "dimension-limit" | "memory-limit" | "invalid-argument" | "out-of-memory" | "output-too-small" | "internal-error" | "unsupported-feature";
74
+ export type ImageErrorCode = "invalid-handle" | "unsupported-format" | "unsupported-color-space" | "malformed-data" | "dimension-limit" | "memory-limit" | "invalid-argument" | "out-of-memory" | "output-too-small" | "internal-error" | "unsupported-feature" | "busy";
69
75
  export declare class ImageError extends Error {
70
76
  readonly code: ImageErrorCode;
71
77
  readonly status: number;
@@ -80,6 +86,7 @@ export declare class NativeImage {
80
86
  static decode(data: Uint8Array | ArrayBuffer): NativeImage;
81
87
  static load(source: ImageSource, options?: ImageLoadOptions): Promise<NativeImage>;
82
88
  static fromRgba(pixels: Uint8Array, width: number, height: number, stride?: number): NativeImage;
89
+ static fromPixels(pixels: Uint8Array, width: number, height: number, options?: PixelImportOptions): NativeImage;
83
90
  private static fromHandle;
84
91
  private guard;
85
92
  get ptr(): ImageHandle;
@@ -105,3 +112,20 @@ export declare class NativeImage {
105
112
  }): void;
106
113
  dispose(): void;
107
114
  }
115
+ export interface NativeImagePoolOptions {
116
+ width: number;
117
+ height: number;
118
+ capacity?: number;
119
+ }
120
+ export declare class NativeImagePool {
121
+ private readonly lib;
122
+ private readonly images;
123
+ private disposed;
124
+ readonly width: number;
125
+ readonly height: number;
126
+ readonly capacity: number;
127
+ constructor(options: NativeImagePoolOptions);
128
+ publishRgba(pixels: Uint8Array, stride?: number): NativeImage | null;
129
+ publishPixels(pixels: Uint8Array, options?: PixelImportOptions): NativeImage | null;
130
+ dispose(): void;
131
+ }
package/index.bun.js CHANGED
@@ -44,7 +44,7 @@ import {
44
44
  mergeKeyAliases,
45
45
  mergeKeyBindings,
46
46
  wrapWithDelegates
47
- } from "./chunk-bun-b3exa82d.js";
47
+ } from "./chunk-bun-bb3k0yt8.js";
48
48
  import {
49
49
  ASCIIFontSelectionHelper,
50
50
  ATTRIBUTE_BASE_BITS,
@@ -204,7 +204,7 @@ import {
204
204
  visualizeRenderableTree,
205
205
  white,
206
206
  yellow
207
- } from "./chunk-bun-2956gvaq.js";
207
+ } from "./chunk-bun-9gqvxy8c.js";
208
208
  // src/post/effects.ts
209
209
  function toU8(value) {
210
210
  return Math.round(Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0)) * 255);
@@ -219,6 +219,9 @@ function setRgb(buffer, base, r, g, b) {
219
219
  buffer[base + 2] = toU8(b);
220
220
  buffer[base + 3] = a;
221
221
  }
222
+ function isGraphemeCell(char) {
223
+ return char >>> 30 >= 2;
224
+ }
222
225
 
223
226
  class DistortionEffect {
224
227
  glitchChancePerSecond = 0.5;
@@ -403,6 +406,7 @@ class DistortionEffect {
403
406
  class VignetteEffect {
404
407
  _strength;
405
408
  precomputedAttenuationCellMask = null;
409
+ precomputedAttenuation = null;
406
410
  cachedWidth = -1;
407
411
  cachedHeight = -1;
408
412
  static zeroMatrix = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
@@ -414,12 +418,14 @@ class VignetteEffect {
414
418
  this.cachedWidth = -1;
415
419
  this.cachedHeight = -1;
416
420
  this.precomputedAttenuationCellMask = null;
421
+ this.precomputedAttenuation = null;
417
422
  }
418
423
  get strength() {
419
424
  return this._strength;
420
425
  }
421
426
  _computeFactors(width, height) {
422
427
  this.precomputedAttenuationCellMask = new Float32Array(width * height * 3);
428
+ this.precomputedAttenuation = new Float32Array(width * height);
423
429
  const centerX = width / 2;
424
430
  const centerY = height / 2;
425
431
  const maxDistSq = centerX * centerX + centerY * centerY;
@@ -437,17 +443,42 @@ class VignetteEffect {
437
443
  this.precomputedAttenuationCellMask[i++] = x;
438
444
  this.precomputedAttenuationCellMask[i++] = y;
439
445
  this.precomputedAttenuationCellMask[i++] = attenuation;
446
+ this.precomputedAttenuation[y * width + x] = attenuation;
440
447
  }
441
448
  }
442
449
  this.cachedWidth = width;
443
450
  this.cachedHeight = height;
444
451
  }
452
+ _preserveGraphemeRuns(buffer) {
453
+ const baseAttenuation = this.precomputedAttenuation;
454
+ const cellMask = this.precomputedAttenuationCellMask;
455
+ const chars = buffer.buffers.char;
456
+ const width = buffer.width;
457
+ for (let y = 0;y < buffer.height; y++) {
458
+ let x = 0;
459
+ while (x < width) {
460
+ const cell = y * width + x;
461
+ if (!isGraphemeCell(chars[cell])) {
462
+ cellMask[cell * 3 + 2] = baseAttenuation[cell];
463
+ x++;
464
+ continue;
465
+ }
466
+ const start = x;
467
+ while (x < width && isGraphemeCell(chars[y * width + x]))
468
+ x++;
469
+ const attenuation = baseAttenuation[y * width + start + Math.floor((x - start) / 2)];
470
+ for (let runX = start;runX < x; runX++)
471
+ cellMask[(y * width + runX) * 3 + 2] = attenuation;
472
+ }
473
+ }
474
+ }
445
475
  apply(buffer) {
446
476
  const width = buffer.width;
447
477
  const height = buffer.height;
448
478
  if (width !== this.cachedWidth || height !== this.cachedHeight || !this.precomputedAttenuationCellMask) {
449
479
  this._computeFactors(width, height);
450
480
  }
481
+ this._preserveGraphemeRuns(buffer);
451
482
  buffer.colorMatrix(VignetteEffect.zeroMatrix, this.precomputedAttenuationCellMask, 1, 3);
452
483
  }
453
484
  }
@@ -5673,7 +5704,8 @@ var STATUS_MESSAGES = [
5673
5704
  "out of memory",
5674
5705
  "image output buffer is too small",
5675
5706
  "internal image error",
5676
- "unsupported image feature"
5707
+ "unsupported image feature",
5708
+ "image is retained"
5677
5709
  ];
5678
5710
  var STATUS_CODES = [
5679
5711
  "internal-error",
@@ -5687,9 +5719,11 @@ var STATUS_CODES = [
5687
5719
  "out-of-memory",
5688
5720
  "output-too-small",
5689
5721
  "internal-error",
5690
- "unsupported-feature"
5722
+ "unsupported-feature",
5723
+ "busy"
5691
5724
  ];
5692
5725
  var INVALID_ARGUMENT_STATUS = 7;
5726
+ var BUSY_STATUS = 12;
5693
5727
 
5694
5728
  class ImageError extends Error {
5695
5729
  code;
@@ -5719,6 +5753,7 @@ var PIXEL_FORMAT_BGRA = {
5719
5753
  rgba8: false,
5720
5754
  bgra8: true
5721
5755
  };
5756
+ var PIXEL_ALPHA_IDS = { straight: 0, opaque: 1 };
5722
5757
  var MAX_ENCODED_BYTES = 64 * 1024 * 1024;
5723
5758
  function imageError(status) {
5724
5759
  return new ImageError(status);
@@ -5738,6 +5773,15 @@ function requireU32(value, name, allowZero = false) {
5738
5773
  }
5739
5774
  return value;
5740
5775
  }
5776
+ function pixelImportOptions(width, options) {
5777
+ const stride = requireU32(options.stride ?? width * 4, "stride");
5778
+ const bgra = requireMappedOption(PIXEL_FORMAT_BGRA, options.format ?? "rgba8", "pixel format");
5779
+ const alpha = requireMappedOption(PIXEL_ALPHA_IDS, options.alpha ?? "straight", "pixel alpha");
5780
+ if (options.colorSpace !== undefined && options.colorSpace !== "srgb") {
5781
+ throw new TypeError(`Unsupported pixel color space: ${String(options.colorSpace)}`);
5782
+ }
5783
+ return { stride, format: Number(bgra), alpha };
5784
+ }
5741
5785
  function requireI32(value, name) {
5742
5786
  if (!Number.isSafeInteger(value) || value < -2147483648 || value > 2147483647) {
5743
5787
  throw new RangeError(`${name} must be an i32 integer`);
@@ -5957,6 +6001,19 @@ class NativeImage {
5957
6001
  throw imageError(10);
5958
6002
  return NativeImage.fromHandle(lib, result.handle);
5959
6003
  }
6004
+ static fromPixels(pixels, width, height, options = {}) {
6005
+ if (!(pixels instanceof Uint8Array))
6006
+ throw new TypeError("pixels must be a Uint8Array");
6007
+ requireU32(width, "width");
6008
+ requireU32(height, "height");
6009
+ const { stride, format, alpha } = pixelImportOptions(width, options);
6010
+ const lib = resolveRenderLib();
6011
+ const result = lib.imageCreateFromPixels(pixels, width, height, stride, format, alpha);
6012
+ checkStatus(result.status);
6013
+ if (!result.handle)
6014
+ throw imageError(10);
6015
+ return NativeImage.fromHandle(lib, result.handle);
6016
+ }
5960
6017
  static fromHandle(lib, handle) {
5961
6018
  const result = lib.imageGetInfo(handle);
5962
6019
  if (result.status !== 0) {
@@ -6088,6 +6145,53 @@ class NativeImage {
6088
6145
  this.handle = null;
6089
6146
  }
6090
6147
  }
6148
+
6149
+ class NativeImagePool {
6150
+ lib;
6151
+ images = [];
6152
+ disposed = false;
6153
+ width;
6154
+ height;
6155
+ capacity;
6156
+ constructor(options) {
6157
+ this.width = requireU32(options.width, "width");
6158
+ this.height = requireU32(options.height, "height");
6159
+ this.capacity = requireU32(options.capacity ?? 3, "capacity");
6160
+ if (this.capacity > 8)
6161
+ throw new RangeError("capacity must be between 1 and 8");
6162
+ this.lib = resolveRenderLib();
6163
+ }
6164
+ publishRgba(pixels, stride = this.width * 4) {
6165
+ return this.publishPixels(pixels, { stride: requireU32(stride, "stride") });
6166
+ }
6167
+ publishPixels(pixels, options = {}) {
6168
+ if (this.disposed)
6169
+ throw new Error("NativeImagePool is disposed");
6170
+ if (!(pixels instanceof Uint8Array))
6171
+ throw new TypeError("pixels must be a Uint8Array");
6172
+ const { stride, format, alpha } = pixelImportOptions(this.width, options);
6173
+ for (const image2 of this.images) {
6174
+ const status = this.lib.imageUpdatePixels(image2.ptr, pixels, stride, format, alpha);
6175
+ if (status === BUSY_STATUS)
6176
+ continue;
6177
+ checkStatus(status);
6178
+ return image2.retain();
6179
+ }
6180
+ if (this.images.length === this.capacity)
6181
+ return null;
6182
+ const image = NativeImage.fromPixels(pixels, this.width, this.height, options);
6183
+ this.images.push(image);
6184
+ return image.retain();
6185
+ }
6186
+ dispose() {
6187
+ if (this.disposed)
6188
+ return;
6189
+ this.disposed = true;
6190
+ for (const image of this.images)
6191
+ image.dispose();
6192
+ this.images.length = 0;
6193
+ }
6194
+ }
6091
6195
  // src/renderables/FrameBuffer.ts
6092
6196
  class FrameBufferRenderable extends Renderable {
6093
6197
  frameBuffer;
@@ -8321,12 +8425,13 @@ class EmbeddedTerminalRenderable extends Renderable {
8321
8425
  if (!this.handle)
8322
8426
  return new Uint8Array;
8323
8427
  const text = textualKey(key);
8428
+ const physical = physicalKey(key);
8324
8429
  return this.lib.embeddedTerminalEncodeKey(this.handle, {
8325
8430
  action: key.eventType === "release" ? "release" : key.repeated ? "repeat" : "press",
8326
- key: physicalKey(key),
8431
+ key: physical,
8327
8432
  mods: modifiers(key),
8328
8433
  text,
8329
- unshiftedCodepoint: key.baseCode ?? physicalUnshiftedCodepoint(key.code)
8434
+ unshiftedCodepoint: key.baseCode ?? physicalUnshiftedCodepoint(physical)
8330
8435
  });
8331
8436
  }
8332
8437
  encodePaste(bytes) {
@@ -8353,6 +8458,8 @@ class EmbeddedTerminalRenderable extends Renderable {
8353
8458
  this.requestRender();
8354
8459
  return false;
8355
8460
  }
8461
+ if (!this.selection && local.behavior === "cell" && local.anchorX === local.focusX && local.anchorY === local.focusY)
8462
+ return false;
8356
8463
  const point = (x, y) => {
8357
8464
  if (y < 0)
8358
8465
  return { x: 0, y: 0 };
@@ -8543,8 +8650,12 @@ function modifiers(input) {
8543
8650
  return value;
8544
8651
  }
8545
8652
  function physicalKey(key) {
8546
- if (key.code)
8653
+ if (key.code && !key.code.startsWith("["))
8547
8654
  return key.code;
8655
+ if (/^[a-z]$/i.test(key.name))
8656
+ return `Key${key.name.toUpperCase()}`;
8657
+ if (/^[0-9]$/.test(key.name))
8658
+ return `Digit${key.name}`;
8548
8659
  return {
8549
8660
  backspace: "Backspace",
8550
8661
  enter: "Enter",
@@ -12922,7 +13033,7 @@ class MarkdownRenderable extends Renderable {
12922
13033
  blockIndex++;
12923
13034
  continue;
12924
13035
  }
12925
- if (existing && !forceTableRefresh && existing.canUpdateInPlace && existing.token.type === block.token.type && this.canUpdateBlockRenderable(existing.renderable, block.token)) {
13036
+ if (existing && existing.canUpdateInPlace && existing.token.type === block.token.type && this.canUpdateBlockRenderable(existing.renderable, block.token)) {
12926
13037
  if (this._renderNode) {
12927
13038
  const custom = this.createTopLevelCustomRenderable(block, blockIndex);
12928
13039
  if (custom.renderable && !custom.canUpdateInPlace) {
@@ -15489,6 +15600,7 @@ export {
15489
15600
  OptimizedBuffer,
15490
15601
  NativeSpanFeed,
15491
15602
  NativeMeasureTargetKind,
15603
+ NativeImagePool,
15492
15604
  NativeImage,
15493
15605
  NativeClipboardStartStatus,
15494
15606
  NativeClipboardShutdownStatus,
@@ -15570,5 +15682,5 @@ export {
15570
15682
  ACHROMATOPSIA_MATRIX
15571
15683
  };
15572
15684
 
15573
- //# debugId=C0029738F074C79064756E2164756E21
15685
+ //# debugId=598A7BAC0738AEF164756E2164756E21
15574
15686
  //# sourceMappingURL=index.bun.js.map