@opentui/core 0.4.2 → 0.4.4

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.
@@ -202,6 +202,17 @@ var POINTER_NEGATIVE = "Pointer must be non-negative";
202
202
  var POINTER_OFFSET_NEGATIVE = "Pointer offset must be non-negative";
203
203
  var POINTER_OFFSET_UNSAFE = "Pointer offset must be a safe integer";
204
204
  var POINTER_UNSAFE = "Pointer exceeds safe integer range";
205
+ var arrayBufferByteLength = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength")?.get;
206
+ function isArrayBuffer(value) {
207
+ if (value === null || typeof value !== "object" || arrayBufferByteLength == null)
208
+ return false;
209
+ try {
210
+ arrayBufferByteLength.call(value);
211
+ return true;
212
+ } catch {
213
+ return false;
214
+ }
215
+ }
205
216
  function unavailable(cause) {
206
217
  throw new Error(FFI_UNAVAILABLE, { cause });
207
218
  }
@@ -351,7 +362,7 @@ function createNodeBackend(nodeFfi) {
351
362
  let closed = false;
352
363
  let libraryClosed = false;
353
364
  return {
354
- symbols: wrapNodeSymbols(functions, symbols, nodeFfi),
365
+ symbols: wrapNodeSymbols(functions, symbols),
355
366
  createCallback(callback, definition) {
356
367
  if (closed) {
357
368
  throw new Error(LIBRARY_CLOSED);
@@ -402,10 +413,10 @@ function toNodeLibraryPath(path) {
402
413
  function normalizeNodeDefinitions(definitions) {
403
414
  return Object.fromEntries(Object.entries(definitions).map(([name, definition]) => [name, normalizeNodeDefinition(definition)]));
404
415
  }
405
- function wrapNodeSymbols(functions, definitions, nodeFfi) {
406
- return Object.fromEntries(Object.entries(functions).map(([name, fn]) => [name, wrapNodeSymbol(fn, definitions[name], nodeFfi)]));
416
+ function wrapNodeSymbols(functions, definitions) {
417
+ return Object.fromEntries(Object.entries(functions).map(([name, fn]) => [name, wrapNodeSymbol(fn, definitions[name])]));
407
418
  }
408
- function wrapNodeSymbol(fn, definition, nodeFfi) {
419
+ function wrapNodeSymbol(fn, definition) {
409
420
  const pointerArgIndexes = (definition.args ?? []).flatMap((type, index) => isNodePointerArgumentType(type) ? [index] : []);
410
421
  if (pointerArgIndexes.length === 0) {
411
422
  return fn;
@@ -413,7 +424,7 @@ function wrapNodeSymbol(fn, definition, nodeFfi) {
413
424
  return (...args) => {
414
425
  const normalizedArgs = args.slice();
415
426
  for (const index of pointerArgIndexes) {
416
- normalizedArgs[index] = toNodePointerArgument(nodeFfi, normalizedArgs[index]);
427
+ normalizedArgs[index] = toNodePointerArgument(normalizedArgs[index]);
417
428
  }
418
429
  return fn(...normalizedArgs);
419
430
  };
@@ -421,7 +432,7 @@ function wrapNodeSymbol(fn, definition, nodeFfi) {
421
432
  function isNodePointerArgumentType(type) {
422
433
  return type === FFIType.ptr || type === FFIType.pointer || type === FFIType.function || type === FFIType.callback;
423
434
  }
424
- function toNodePointerArgument(nodeFfi, value) {
435
+ function toNodePointerArgument(value) {
425
436
  if (value == null) {
426
437
  return 0n;
427
438
  }
@@ -429,27 +440,30 @@ function toNodePointerArgument(nodeFfi, value) {
429
440
  return toBigIntPointer(value);
430
441
  }
431
442
  if (ArrayBuffer.isView(value)) {
443
+ if (!isArrayBuffer(value.buffer)) {
444
+ throw new TypeError(NODE_PTR_VALUE);
445
+ }
432
446
  if (value.byteLength === 0) {
433
447
  return 0n;
434
448
  }
435
- return toNodeSourcePointer(nodeFfi, value);
449
+ return value;
436
450
  }
437
- if (value instanceof ArrayBuffer) {
451
+ if (isArrayBuffer(value)) {
438
452
  if (value.byteLength === 0) {
439
453
  return 0n;
440
454
  }
441
- return toNodeSourcePointer(nodeFfi, value);
455
+ return value;
442
456
  }
443
457
  throw new TypeError(NODE_POINTER_ARGUMENT);
444
458
  }
445
459
  function toNodeSourcePointer(nodeFfi, value) {
446
460
  if (ArrayBuffer.isView(value)) {
447
- if (!(value.buffer instanceof ArrayBuffer)) {
461
+ if (!isArrayBuffer(value.buffer)) {
448
462
  throw new TypeError(NODE_PTR_VALUE);
449
463
  }
450
464
  return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset);
451
465
  }
452
- if (value instanceof ArrayBuffer) {
466
+ if (isArrayBuffer(value)) {
453
467
  return nodeFfi.getRawPointer(value);
454
468
  }
455
469
  throw new TypeError(NODE_PTR_VALUE);
@@ -10818,7 +10832,7 @@ class TextBuffer {
10818
10832
  }
10819
10833
  }
10820
10834
 
10821
- // ../../node_modules/.bun/bun-ffi-structs@0.2.3+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
10835
+ // ../../node_modules/.bun/bun-ffi-structs@0.2.4+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
10822
10836
  var FFI_LOAD_ERROR = "bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi).";
10823
10837
  var backend2 = await loadBackend2();
10824
10838
  function unavailable2(cause) {
@@ -11068,6 +11082,20 @@ function defineStruct(fields, structDefOptions) {
11068
11082
  size = typeSizes[typeOrStruct];
11069
11083
  align = typeAlignments[typeOrStruct];
11070
11084
  ({ pack, unpack } = primitivePackers(typeOrStruct));
11085
+ if (typeOrStruct === "pointer") {
11086
+ pack = (view, off, val) => {
11087
+ if (val instanceof ArrayBuffer || ArrayBuffer.isView(val)) {
11088
+ if (val.byteLength === 0) {
11089
+ pointerPacker(view, off, null);
11090
+ return;
11091
+ }
11092
+ pointerPacker(view, off, ptr2(val));
11093
+ retainPointerTarget(view.buffer, val);
11094
+ return;
11095
+ }
11096
+ pointerPacker(view, off, val);
11097
+ };
11098
+ }
11071
11099
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "cstring") {
11072
11100
  size = pointerSize;
11073
11101
  align = pointerSize;
@@ -11541,7 +11569,7 @@ function defineStruct(fields, structDefOptions) {
11541
11569
  }
11542
11570
 
11543
11571
  // src/zig-structs.ts
11544
- var rgbaPackTransform = (rgba) => rgba ? ptr(rgba.buffer) : null;
11572
+ var rgbaPackTransform = (rgba) => rgba?.buffer ?? null;
11545
11573
  var rgbaUnpackTransform = (ptr3) => ptr3 ? RGBA.fromArray(new Uint16Array(toArrayBuffer(ptr3, 0, 8))) : undefined;
11546
11574
  var StyledChunkStruct = defineStruct([
11547
11575
  ["text", "char*"],
@@ -11744,6 +11772,33 @@ var ReserveInfoStruct = defineStruct([
11744
11772
  len: value.len
11745
11773
  })
11746
11774
  });
11775
+ var NativeAudioStreamFormat = {
11776
+ Mp3: 1,
11777
+ Flac: 2
11778
+ };
11779
+ var NativeAudioStreamState = {
11780
+ Initializing: 0,
11781
+ Buffering: 1,
11782
+ Playing: 2,
11783
+ Ended: 3,
11784
+ Failed: 4,
11785
+ Cancelled: 5,
11786
+ Reconnecting: 6
11787
+ };
11788
+ var NativeAudioStreamStateNames = [
11789
+ "initializing",
11790
+ "buffering",
11791
+ "playing",
11792
+ "ended",
11793
+ "errored",
11794
+ "disposed",
11795
+ "reconnecting"
11796
+ ];
11797
+ var NativeAudioStreamCloseReason = {
11798
+ PreserveNativeTerminal: 0,
11799
+ TransportError: 1,
11800
+ Disposed: 2
11801
+ };
11747
11802
  var AudioCreateOptionsStruct = defineStruct([
11748
11803
  ["sampleRate", "u32", { default: 48000 }],
11749
11804
  ["playbackChannels", "u32", { default: 2 }]
@@ -11771,6 +11826,29 @@ var AudioVoiceOptionsStruct = defineStruct([
11771
11826
  ["loop", "bool_u8", { default: false }],
11772
11827
  ["groupId", "u32", { default: 0 }]
11773
11828
  ]);
11829
+ var AudioStreamCreateOptionsStruct = defineStruct([
11830
+ ["capacityMs", "u32"],
11831
+ ["startupMs", "u32"],
11832
+ ["resumeMs", "u32"],
11833
+ ["volume", "f32"],
11834
+ ["pan", "f32"],
11835
+ ["groupId", "u32"],
11836
+ ["maxProbeBytes", "u32"],
11837
+ ["format", "u32"]
11838
+ ]);
11839
+ var AudioStreamStatsStruct = defineStruct([
11840
+ ["bytesReceived", "u64"],
11841
+ ["framesDecoded", "u64"],
11842
+ ["framesPlayed", "u64"],
11843
+ ["state", "u32"],
11844
+ ["sampleRate", "u32"],
11845
+ ["channels", "u32"],
11846
+ ["bufferedFrames", "u32"],
11847
+ ["capacityFrames", "u32"],
11848
+ ["underruns", "u32"],
11849
+ ["errorCode", "i32"],
11850
+ ["readyGeneration", "u32"]
11851
+ ]);
11774
11852
  var AudioStatsStruct = defineStruct([
11775
11853
  ["soundsLoaded", "u32"],
11776
11854
  ["voicesActive", "u32"],
@@ -11781,6 +11859,9 @@ var AudioStatsStruct = defineStruct([
11781
11859
  ]);
11782
11860
 
11783
11861
  // src/zig.ts
11862
+ var NativeAudioStreamState2 = NativeAudioStreamState;
11863
+ var NativeAudioStreamCloseReason2 = NativeAudioStreamCloseReason;
11864
+ var NativeAudioStreamFormat2 = NativeAudioStreamFormat;
11784
11865
  registerEnvVar({
11785
11866
  name: "OPENTUI_LIBC",
11786
11867
  description: "Select Linux native libc package. Supported values: glibc, musl.",
@@ -11894,6 +11975,9 @@ function toSafeFFIU32Length(value, label) {
11894
11975
  }
11895
11976
  return value;
11896
11977
  }
11978
+ function isFFIU32(value) {
11979
+ return Number.isInteger(value) && value >= 0 && value <= MAX_FFI_U32;
11980
+ }
11897
11981
  function ptrOrNull(value) {
11898
11982
  return value.byteLength === 0 ? null : ptr(value);
11899
11983
  }
@@ -11918,6 +12002,22 @@ function getOpenTUILib(libPath) {
11918
12002
  args: ["u32"],
11919
12003
  returns: "void"
11920
12004
  },
12005
+ createNativeRenderable: {
12006
+ args: [],
12007
+ returns: "u32"
12008
+ },
12009
+ destroyNativeRenderable: {
12010
+ args: ["u32"],
12011
+ returns: "void"
12012
+ },
12013
+ nativeRenderableAttachYogaNode: {
12014
+ args: ["u32", "ptr"],
12015
+ returns: "bool"
12016
+ },
12017
+ nativeRenderableSetMeasureTarget: {
12018
+ args: ["u32", "u32", "u32"],
12019
+ returns: "bool"
12020
+ },
11921
12021
  createRenderer: {
11922
12022
  args: ["u32", "u32", "u8", "u8", "ptr"],
11923
12023
  returns: "u32"
@@ -13051,7 +13151,7 @@ function getOpenTUILib(libPath) {
13051
13151
  returns: "u64"
13052
13152
  },
13053
13153
  yogaNodeSetMeasureFunc: {
13054
- args: ["ptr", "ptr"],
13154
+ args: ["ptr", "bool"],
13055
13155
  returns: "void"
13056
13156
  },
13057
13157
  yogaNodeUnsetMeasureFunc: {
@@ -13063,7 +13163,7 @@ function getOpenTUILib(libPath) {
13063
13163
  returns: "bool"
13064
13164
  },
13065
13165
  yogaNodeSetDirtiedFunc: {
13066
- args: ["ptr", "ptr"],
13166
+ args: ["ptr", "bool"],
13067
13167
  returns: "void"
13068
13168
  },
13069
13169
  yogaNodeUnsetDirtiedFunc: {
@@ -13074,6 +13174,14 @@ function getOpenTUILib(libPath) {
13074
13174
  args: ["f32", "f32"],
13075
13175
  returns: "void"
13076
13176
  },
13177
+ yogaSetMeasureCallback: {
13178
+ args: ["ptr"],
13179
+ returns: "void"
13180
+ },
13181
+ yogaSetDirtiedCallback: {
13182
+ args: ["ptr"],
13183
+ returns: "void"
13184
+ },
13077
13185
  createAudioEngine: {
13078
13186
  args: ["ptr"],
13079
13187
  returns: "u32"
@@ -13118,6 +13226,42 @@ function getOpenTUILib(libPath) {
13118
13226
  args: ["u32"],
13119
13227
  returns: "i32"
13120
13228
  },
13229
+ audioCreateStream: {
13230
+ args: ["u32", "ptr", "ptr"],
13231
+ returns: "i32"
13232
+ },
13233
+ audioWriteStream: {
13234
+ args: ["u32", "u32", "ptr", "u32"],
13235
+ returns: "i32"
13236
+ },
13237
+ audioEndStream: {
13238
+ args: ["u32", "u32"],
13239
+ returns: "i32"
13240
+ },
13241
+ audioRestartStream: {
13242
+ args: ["u32", "u32"],
13243
+ returns: "i32"
13244
+ },
13245
+ audioSetStreamVolume: {
13246
+ args: ["u32", "u32", "f32"],
13247
+ returns: "i32"
13248
+ },
13249
+ audioSetStreamPan: {
13250
+ args: ["u32", "u32", "f32"],
13251
+ returns: "i32"
13252
+ },
13253
+ audioSetStreamGroup: {
13254
+ args: ["u32", "u32", "u32"],
13255
+ returns: "i32"
13256
+ },
13257
+ audioGetStreamStats: {
13258
+ args: ["u32", "u32", "ptr"],
13259
+ returns: "i32"
13260
+ },
13261
+ audioCloseStream: {
13262
+ args: ["u32", "u32", "u32", "ptr"],
13263
+ returns: "i32"
13264
+ },
13121
13265
  audioLoad: {
13122
13266
  args: ["u32", "ptr", "u32", "ptr"],
13123
13267
  returns: "i32"
@@ -13364,6 +13508,11 @@ var LogLevel2;
13364
13508
  LogLevel3[LogLevel3["Info"] = 2] = "Info";
13365
13509
  LogLevel3[LogLevel3["Debug"] = 3] = "Debug";
13366
13510
  })(LogLevel2 ||= {});
13511
+ var NativeMeasureTargetKind = {
13512
+ None: 0,
13513
+ TextBufferView: 1,
13514
+ EditorView: 2
13515
+ };
13367
13516
 
13368
13517
  class FFIRenderLib {
13369
13518
  opentui;
@@ -13376,6 +13525,21 @@ class FFIRenderLib {
13376
13525
  _anyEventHandlers = [];
13377
13526
  nativeSpanFeedCallbackWrapper = null;
13378
13527
  nativeSpanFeedHandlers = new Map;
13528
+ createNativeRenderable() {
13529
+ const handle = this.opentui.symbols.createNativeRenderable();
13530
+ if (!handle)
13531
+ throw new Error("Failed to create native renderable");
13532
+ return handle;
13533
+ }
13534
+ destroyNativeRenderable(handle) {
13535
+ this.opentui.symbols.destroyNativeRenderable(handle);
13536
+ }
13537
+ nativeRenderableAttachYogaNode(handle, node) {
13538
+ return Boolean(this.opentui.symbols.nativeRenderableAttachYogaNode(handle, node));
13539
+ }
13540
+ nativeRenderableSetMeasureTarget(handle, kind, target) {
13541
+ return Boolean(this.opentui.symbols.nativeRenderableSetMeasureTarget(handle, kind, target));
13542
+ }
13379
13543
  constructor(libPath) {
13380
13544
  this.opentui = getOpenTUILib(libPath);
13381
13545
  try {
@@ -13436,6 +13600,8 @@ class FFIRenderLib {
13436
13600
  this.opentui.symbols.destroyEventSink(this.eventSinkPtr);
13437
13601
  this.eventSinkPtr = null;
13438
13602
  }
13603
+ this.yogaSetMeasureCallback(null);
13604
+ this.yogaSetDirtiedCallback(null);
13439
13605
  this.setLogCallback(null);
13440
13606
  } finally {
13441
13607
  try {
@@ -13746,7 +13912,7 @@ class FFIRenderLib {
13746
13912
  const blinking = options.blinking != null ? options.blinking ? 1 : 0 : 255;
13747
13913
  const cursor = options.cursor != null ? MOUSE_STYLE_TO_ID[options.cursor] : 255;
13748
13914
  const buffer = CursorStyleOptionsStruct.pack({ style, blinking, color: options.color, cursor });
13749
- this.opentui.symbols.setCursorStyleOptions(renderer, ptr(buffer));
13915
+ this.opentui.symbols.setCursorStyleOptions(renderer, buffer);
13750
13916
  }
13751
13917
  render(renderer, force) {
13752
13918
  return this.opentui.symbols.render(renderer, ffiBool(force));
@@ -14034,17 +14200,17 @@ class FFIRenderLib {
14034
14200
  yogaNodeStyleGetValue(node, kind, edgeOrGutter) {
14035
14201
  return this.opentui.symbols.yogaNodeStyleGetValue(node, kind, edgeOrGutter);
14036
14202
  }
14037
- yogaNodeSetMeasureFunc(node, callback) {
14038
- this.opentui.symbols.yogaNodeSetMeasureFunc(node, callback);
14203
+ yogaNodeSetMeasureFunc(node, enabled) {
14204
+ this.opentui.symbols.yogaNodeSetMeasureFunc(node, ffiBool(enabled));
14039
14205
  }
14040
14206
  yogaNodeUnsetMeasureFunc(node) {
14041
14207
  this.opentui.symbols.yogaNodeUnsetMeasureFunc(node);
14042
14208
  }
14043
14209
  yogaNodeHasMeasureFunc(node) {
14044
- return this.opentui.symbols.yogaNodeHasMeasureFunc(node);
14210
+ return Boolean(this.opentui.symbols.yogaNodeHasMeasureFunc(node));
14045
14211
  }
14046
- yogaNodeSetDirtiedFunc(node, callback) {
14047
- this.opentui.symbols.yogaNodeSetDirtiedFunc(node, callback);
14212
+ yogaNodeSetDirtiedFunc(node, enabled) {
14213
+ this.opentui.symbols.yogaNodeSetDirtiedFunc(node, ffiBool(enabled));
14048
14214
  }
14049
14215
  yogaNodeUnsetDirtiedFunc(node) {
14050
14216
  this.opentui.symbols.yogaNodeUnsetDirtiedFunc(node);
@@ -14052,6 +14218,12 @@ class FFIRenderLib {
14052
14218
  yogaStoreMeasureResult(width, height) {
14053
14219
  this.opentui.symbols.yogaStoreMeasureResult(width, height);
14054
14220
  }
14221
+ yogaSetMeasureCallback(callback) {
14222
+ this.opentui.symbols.yogaSetMeasureCallback(callback);
14223
+ }
14224
+ yogaSetDirtiedCallback(callback) {
14225
+ this.opentui.symbols.yogaSetDirtiedCallback(callback);
14226
+ }
14055
14227
  createYogaMeasureCallback(callback) {
14056
14228
  return this.opentui.createCallback(callback, {
14057
14229
  args: ["ptr", "f32", "u32", "f32", "u32"],
@@ -14060,7 +14232,7 @@ class FFIRenderLib {
14060
14232
  }
14061
14233
  createYogaDirtiedCallback(callback) {
14062
14234
  return this.opentui.createCallback(callback, {
14063
- args: [],
14235
+ args: ["ptr"],
14064
14236
  returns: "void"
14065
14237
  });
14066
14238
  }
@@ -14140,7 +14312,7 @@ class FFIRenderLib {
14140
14312
  return;
14141
14313
  }
14142
14314
  const chunksBuffer = StyledChunkStruct.packList(chunks);
14143
- this.opentui.symbols.textBufferSetStyledText(buffer, ptr(chunksBuffer), chunks.length);
14315
+ this.opentui.symbols.textBufferSetStyledText(buffer, chunksBuffer, chunks.length);
14144
14316
  }
14145
14317
  textBufferGetLineCount(buffer) {
14146
14318
  return this.opentui.symbols.textBufferGetLineCount(buffer);
@@ -14844,7 +15016,12 @@ class FFIRenderLib {
14844
15016
  this.opentui.symbols.audioClearPlaybackDeviceSelection(engine);
14845
15017
  }
14846
15018
  audioStart(engine, options) {
14847
- const optionsBuffer = options == null ? null : AudioStartOptionsStruct.pack(options);
15019
+ let optionsBuffer;
15020
+ try {
15021
+ optionsBuffer = options == null ? null : AudioStartOptionsStruct.pack(options);
15022
+ } catch {
15023
+ return -1;
15024
+ }
14848
15025
  return this.opentui.symbols.audioStart(engine, optionsBuffer ? ptr(optionsBuffer) : null);
14849
15026
  }
14850
15027
  audioStartMixer(engine) {
@@ -14853,6 +15030,52 @@ class FFIRenderLib {
14853
15030
  audioStop(engine) {
14854
15031
  return this.opentui.symbols.audioStop(engine);
14855
15032
  }
15033
+ audioCreateStream(engine, options) {
15034
+ if (!isFFIU32(options.groupId) || options.format !== NativeAudioStreamFormat2.Mp3 && options.format !== NativeAudioStreamFormat2.Flac) {
15035
+ return { status: -1, streamId: null };
15036
+ }
15037
+ const optionsBuffer = AudioStreamCreateOptionsStruct.pack(options);
15038
+ const outBuffer = new ArrayBuffer(4);
15039
+ const status = this.opentui.symbols.audioCreateStream(engine, optionsBuffer, outBuffer);
15040
+ if (status !== 0)
15041
+ return { status, streamId: null };
15042
+ return { status, streamId: new Uint32Array(outBuffer)[0] ?? null };
15043
+ }
15044
+ audioWriteStream(engine, streamId, data) {
15045
+ const dataLength = toSafeFFIU32Length(data.byteLength, "Audio stream data length");
15046
+ return this.opentui.symbols.audioWriteStream(engine, streamId, dataLength === 0 ? null : data, dataLength);
15047
+ }
15048
+ audioEndStream(engine, streamId) {
15049
+ return this.opentui.symbols.audioEndStream(engine, streamId);
15050
+ }
15051
+ audioRestartStream(engine, streamId) {
15052
+ return this.opentui.symbols.audioRestartStream(engine, streamId);
15053
+ }
15054
+ audioSetStreamVolume(engine, streamId, volume) {
15055
+ return this.opentui.symbols.audioSetStreamVolume(engine, streamId, volume);
15056
+ }
15057
+ audioSetStreamPan(engine, streamId, pan) {
15058
+ return this.opentui.symbols.audioSetStreamPan(engine, streamId, pan);
15059
+ }
15060
+ audioSetStreamGroup(engine, streamId, groupId) {
15061
+ if (!isFFIU32(groupId))
15062
+ return -1;
15063
+ return this.opentui.symbols.audioSetStreamGroup(engine, streamId, groupId);
15064
+ }
15065
+ audioGetStreamStats(engine, streamId) {
15066
+ const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15067
+ const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, outBuffer);
15068
+ if (status !== 0)
15069
+ return null;
15070
+ return AudioStreamStatsStruct.unpack(outBuffer);
15071
+ }
15072
+ audioCloseStream(engine, streamId, reason) {
15073
+ const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15074
+ const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, outBuffer);
15075
+ if (status !== 0)
15076
+ return { status, stats: null };
15077
+ return { status, stats: AudioStreamStatsStruct.unpack(outBuffer) };
15078
+ }
14856
15079
  audioLoad(engine, data) {
14857
15080
  const outBuffer = new ArrayBuffer(4);
14858
15081
  const dataLength = toSafeFFIU32Length(data.byteLength, "Audio data length");
@@ -14867,6 +15090,8 @@ class FFIRenderLib {
14867
15090
  return this.opentui.symbols.audioUnload(engine, soundId);
14868
15091
  }
14869
15092
  audioPlay(engine, soundId, options) {
15093
+ if (options?.groupId !== undefined && !isFFIU32(options.groupId))
15094
+ return { status: -1, voiceId: null };
14870
15095
  const outBuffer = new ArrayBuffer(4);
14871
15096
  const optionsBuffer = options ? AudioVoiceOptionsStruct.pack(options) : null;
14872
15097
  const status = this.opentui.symbols.audioPlay(engine, soundId, optionsBuffer ? ptr(optionsBuffer) : null, ptr(outBuffer));
@@ -14880,6 +15105,8 @@ class FFIRenderLib {
14880
15105
  return this.opentui.symbols.audioStopVoice(engine, voiceId);
14881
15106
  }
14882
15107
  audioSetVoiceGroup(engine, voiceId, groupId) {
15108
+ if (!isFFIU32(groupId))
15109
+ return -1;
14883
15110
  return this.opentui.symbols.audioSetVoiceGroup(engine, voiceId, groupId);
14884
15111
  }
14885
15112
  audioCreateGroup(engine, name) {
@@ -15028,7 +15255,7 @@ class FFIRenderLib {
15028
15255
  return;
15029
15256
  }
15030
15257
  const chunksBuffer = StyledChunkStruct.packList(nonEmptyChunks);
15031
- this.opentui.symbols.editorViewSetPlaceholderStyledText(view, ptr(chunksBuffer), nonEmptyChunks.length);
15258
+ this.opentui.symbols.editorViewSetPlaceholderStyledText(view, chunksBuffer, nonEmptyChunks.length);
15032
15259
  }
15033
15260
  editorViewSetTabIndicator(view, indicator) {
15034
15261
  this.opentui.symbols.editorViewSetTabIndicator(view, indicator);
@@ -15317,11 +15544,52 @@ var YogaEdgeLayoutKind = {
15317
15544
  };
15318
15545
  var UNDEFINED_VALUE = { unit: 0 /* Undefined */, value: NaN };
15319
15546
  var nodeRegistry = new Map;
15547
+ var measureRegistry = new Map;
15548
+ var dirtiedRegistry = new Map;
15549
+ var measureCallback = null;
15550
+ var measureCallbackLib = null;
15551
+ var dirtiedCallback = null;
15552
+ var dirtiedCallbackLib = null;
15320
15553
  function lib() {
15321
15554
  return resolveRenderLib();
15322
15555
  }
15323
- function pointerKey(pointer) {
15324
- return String(pointer);
15556
+ function ensureMeasureCallback() {
15557
+ const renderLib = lib();
15558
+ if (measureCallback?.ptr && measureCallbackLib === renderLib)
15559
+ return;
15560
+ const callback = (node, width, widthMode, height, heightMode) => {
15561
+ const measureFunc = node ? measureRegistry.get(node) : undefined;
15562
+ const result = measureFunc?.(width, widthMode, height, heightMode);
15563
+ renderLib.yogaStoreMeasureResult(result?.width ?? NaN, result?.height ?? NaN);
15564
+ };
15565
+ measureCallback = renderLib.createYogaMeasureCallback(callback);
15566
+ if (!measureCallback.ptr) {
15567
+ measureCallback.close();
15568
+ measureCallback = null;
15569
+ throw new Error("Failed to create Yoga measure callback");
15570
+ }
15571
+ renderLib.yogaSetMeasureCallback(measureCallback.ptr);
15572
+ measureCallbackLib = renderLib;
15573
+ }
15574
+ function ensureDirtiedCallback() {
15575
+ const renderLib = lib();
15576
+ if (dirtiedCallback?.ptr && dirtiedCallbackLib === renderLib)
15577
+ return;
15578
+ const callback = (node) => {
15579
+ if (!node)
15580
+ return;
15581
+ const registration = dirtiedRegistry.get(node);
15582
+ if (registration)
15583
+ registration.callback(registration.node);
15584
+ };
15585
+ dirtiedCallback = renderLib.createYogaDirtiedCallback(callback);
15586
+ if (!dirtiedCallback.ptr) {
15587
+ dirtiedCallback.close();
15588
+ dirtiedCallback = null;
15589
+ throw new Error("Failed to create Yoga dirtied callback");
15590
+ }
15591
+ renderLib.yogaSetDirtiedCallback(dirtiedCallback.ptr);
15592
+ dirtiedCallbackLib = renderLib;
15325
15593
  }
15326
15594
  function isValueObject(value) {
15327
15595
  return typeof value === "object" && value !== null && "unit" in value && "value" in value;
@@ -15424,11 +15692,9 @@ class Config {
15424
15692
  class Node {
15425
15693
  ptr;
15426
15694
  freed = false;
15427
- measureCallback = null;
15428
- dirtiedCallback = null;
15429
15695
  constructor(ptr3) {
15430
15696
  this.ptr = ptr3;
15431
- nodeRegistry.set(pointerKey(ptr3), this);
15697
+ nodeRegistry.set(ptr3, this);
15432
15698
  }
15433
15699
  static create(config) {
15434
15700
  return Node.fromPointer(config ? lib().yogaNodeCreateWithConfig(config.ptr) : lib().yogaNodeCreate());
@@ -15446,8 +15712,7 @@ class Node {
15446
15712
  node.free();
15447
15713
  }
15448
15714
  static fromPointer(ptr3) {
15449
- const key = pointerKey(ptr3);
15450
- const existing = nodeRegistry.get(key);
15715
+ const existing = nodeRegistry.get(ptr3);
15451
15716
  if (existing)
15452
15717
  return existing;
15453
15718
  return new Node(ptr3);
@@ -15468,8 +15733,7 @@ class Node {
15468
15733
  return;
15469
15734
  const nodes = this.collectSubtree([]);
15470
15735
  for (const node of nodes) {
15471
- node.closeMeasureCallback();
15472
- node.closeDirtiedCallback();
15736
+ node.unregisterCallbacks();
15473
15737
  }
15474
15738
  lib().yogaNodeFreeRecursive(this.ptr);
15475
15739
  for (const node of nodes) {
@@ -15823,23 +16087,15 @@ class Node {
15823
16087
  this.unsetMeasureFunc();
15824
16088
  if (!measureFunc)
15825
16089
  return;
15826
- const callback = (_node, width, widthMode, height, heightMode) => {
15827
- const result = measureFunc(width, widthMode, height, heightMode);
15828
- lib().yogaStoreMeasureResult(result.width ?? NaN, result.height ?? NaN);
15829
- };
15830
- this.measureCallback = lib().createYogaMeasureCallback(callback);
15831
- if (!this.measureCallback.ptr) {
15832
- this.measureCallback.close();
15833
- this.measureCallback = null;
15834
- throw new Error("Failed to create Yoga measure callback");
15835
- }
15836
- lib().yogaNodeSetMeasureFunc(this.ptr, this.measureCallback.ptr);
16090
+ ensureMeasureCallback();
16091
+ measureRegistry.set(this.ptr, measureFunc);
16092
+ lib().yogaNodeSetMeasureFunc(this.ptr, true);
15837
16093
  }
15838
16094
  unsetMeasureFunc() {
15839
16095
  if (this.freed)
15840
16096
  return;
15841
16097
  lib().yogaNodeUnsetMeasureFunc(this.ptr);
15842
- this.closeMeasureCallback();
16098
+ measureRegistry.delete(this.ptr);
15843
16099
  }
15844
16100
  hasMeasureFunc() {
15845
16101
  if (this.freed)
@@ -15852,22 +16108,15 @@ class Node {
15852
16108
  this.unsetDirtiedFunc();
15853
16109
  if (!dirtiedFunc)
15854
16110
  return;
15855
- const callback = () => {
15856
- dirtiedFunc(this);
15857
- };
15858
- this.dirtiedCallback = lib().createYogaDirtiedCallback(callback);
15859
- if (!this.dirtiedCallback.ptr) {
15860
- this.dirtiedCallback.close();
15861
- this.dirtiedCallback = null;
15862
- throw new Error("Failed to create Yoga dirtied callback");
15863
- }
15864
- lib().yogaNodeSetDirtiedFunc(this.ptr, this.dirtiedCallback.ptr);
16111
+ ensureDirtiedCallback();
16112
+ dirtiedRegistry.set(this.ptr, { node: this, callback: dirtiedFunc });
16113
+ lib().yogaNodeSetDirtiedFunc(this.ptr, true);
15865
16114
  }
15866
16115
  unsetDirtiedFunc() {
15867
16116
  if (this.freed)
15868
16117
  return;
15869
16118
  lib().yogaNodeUnsetDirtiedFunc(this.ptr);
15870
- this.closeDirtiedCallback();
16119
+ dirtiedRegistry.delete(this.ptr);
15871
16120
  }
15872
16121
  setEnum(kind, value) {
15873
16122
  if (this.freed)
@@ -15907,21 +16156,14 @@ class Node {
15907
16156
  nodes.push(this);
15908
16157
  return nodes;
15909
16158
  }
15910
- closeMeasureCallback() {
15911
- if (!this.measureCallback)
15912
- return;
15913
- this.measureCallback.close();
15914
- this.measureCallback = null;
15915
- }
15916
- closeDirtiedCallback() {
15917
- if (!this.dirtiedCallback)
15918
- return;
15919
- this.dirtiedCallback.close();
15920
- this.dirtiedCallback = null;
16159
+ unregisterCallbacks() {
16160
+ measureRegistry.delete(this.ptr);
16161
+ dirtiedRegistry.delete(this.ptr);
15921
16162
  }
15922
16163
  markFreed() {
16164
+ this.unregisterCallbacks();
15923
16165
  this.freed = true;
15924
- nodeRegistry.delete(pointerKey(this.ptr));
16166
+ nodeRegistry.delete(this.ptr);
15925
16167
  }
15926
16168
  }
15927
16169
  var Yoga = {
@@ -16020,7 +16262,7 @@ var Yoga = {
16020
16262
  };
16021
16263
  var yoga_default = Yoga;
16022
16264
 
16023
- export { toArrayBuffer, sleep, stringWidth2 as stringWidth, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, getTreeSitterClient, destroyTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, ClipboardTarget, Clipboard, detectLinks, OptimizedBuffer, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, Align, BoxSizing, Dimension, Direction, Display, Edge, Errata, ExperimentalFeature, FlexDirection, Gutter, Justify, LogLevel as LogLevel1, MeasureMode, NodeType, Overflow, PositionType, Unit, Wrap, ALIGN_AUTO, ALIGN_FLEX_START, ALIGN_CENTER, ALIGN_FLEX_END, ALIGN_STRETCH, ALIGN_BASELINE, ALIGN_SPACE_BETWEEN, ALIGN_SPACE_AROUND, ALIGN_SPACE_EVENLY, BOX_SIZING_BORDER_BOX, BOX_SIZING_CONTENT_BOX, DIMENSION_WIDTH, DIMENSION_HEIGHT, DIRECTION_INHERIT, DIRECTION_LTR, DIRECTION_RTL, DISPLAY_FLEX, DISPLAY_NONE, DISPLAY_CONTENTS, EDGE_LEFT, EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_START, EDGE_END, EDGE_HORIZONTAL, EDGE_VERTICAL, EDGE_ALL, ERRATA_NONE, ERRATA_STRETCH_FLEX_BASIS, ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, ERRATA_ALL, ERRATA_CLASSIC, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE, FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, GUTTER_COLUMN, GUTTER_ROW, GUTTER_ALL, JUSTIFY_FLEX_START, JUSTIFY_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN, JUSTIFY_SPACE_AROUND, JUSTIFY_SPACE_EVENLY, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, LOG_LEVEL_FATAL, MEASURE_MODE_UNDEFINED, MEASURE_MODE_EXACTLY, MEASURE_MODE_AT_MOST, NODE_TYPE_DEFAULT, NODE_TYPE_TEXT, OVERFLOW_VISIBLE, OVERFLOW_HIDDEN, OVERFLOW_SCROLL, POSITION_TYPE_STATIC, POSITION_TYPE_RELATIVE, POSITION_TYPE_ABSOLUTE, UNIT_UNDEFINED, UNIT_POINT, UNIT_PERCENT, UNIT_AUTO, WRAP_NO_WRAP, WRAP_WRAP, WRAP_WRAP_REVERSE, Config, Node, exports_yoga, yoga_default };
16265
+ export { toArrayBuffer, sleep, stringWidth2 as stringWidth, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, getTreeSitterClient, destroyTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, ClipboardTarget, Clipboard, detectLinks, OptimizedBuffer, TextBuffer, SpanInfoStruct, NativeAudioStreamFormat, NativeAudioStreamState, NativeAudioStreamStateNames, NativeAudioStreamCloseReason, NativeAudioStreamState2 as NativeAudioStreamState1, NativeAudioStreamCloseReason2 as NativeAudioStreamCloseReason1, NativeAudioStreamFormat2 as NativeAudioStreamFormat1, LogLevel2 as LogLevel, NativeMeasureTargetKind, setRenderLibPath, resolveRenderLib, Align, BoxSizing, Dimension, Direction, Display, Edge, Errata, ExperimentalFeature, FlexDirection, Gutter, Justify, LogLevel as LogLevel1, MeasureMode, NodeType, Overflow, PositionType, Unit, Wrap, ALIGN_AUTO, ALIGN_FLEX_START, ALIGN_CENTER, ALIGN_FLEX_END, ALIGN_STRETCH, ALIGN_BASELINE, ALIGN_SPACE_BETWEEN, ALIGN_SPACE_AROUND, ALIGN_SPACE_EVENLY, BOX_SIZING_BORDER_BOX, BOX_SIZING_CONTENT_BOX, DIMENSION_WIDTH, DIMENSION_HEIGHT, DIRECTION_INHERIT, DIRECTION_LTR, DIRECTION_RTL, DISPLAY_FLEX, DISPLAY_NONE, DISPLAY_CONTENTS, EDGE_LEFT, EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_START, EDGE_END, EDGE_HORIZONTAL, EDGE_VERTICAL, EDGE_ALL, ERRATA_NONE, ERRATA_STRETCH_FLEX_BASIS, ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, ERRATA_ALL, ERRATA_CLASSIC, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE, FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, GUTTER_COLUMN, GUTTER_ROW, GUTTER_ALL, JUSTIFY_FLEX_START, JUSTIFY_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN, JUSTIFY_SPACE_AROUND, JUSTIFY_SPACE_EVENLY, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, LOG_LEVEL_FATAL, MEASURE_MODE_UNDEFINED, MEASURE_MODE_EXACTLY, MEASURE_MODE_AT_MOST, NODE_TYPE_DEFAULT, NODE_TYPE_TEXT, OVERFLOW_VISIBLE, OVERFLOW_HIDDEN, OVERFLOW_SCROLL, POSITION_TYPE_STATIC, POSITION_TYPE_RELATIVE, POSITION_TYPE_ABSOLUTE, UNIT_UNDEFINED, UNIT_POINT, UNIT_PERCENT, UNIT_AUTO, WRAP_NO_WRAP, WRAP_WRAP, WRAP_WRAP_REVERSE, Config, Node, exports_yoga, yoga_default };
16024
16266
 
16025
- //# debugId=7DC0036015F75D5364756E2164756E21
16026
- //# sourceMappingURL=index-x7n320jr.js.map
16267
+ //# debugId=ABFD53867F2F7F9C64756E2164756E21
16268
+ //# sourceMappingURL=index-za1krqsf.js.map