@yodaos-pkg/ink 0.8.0 → 0.9.1

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/README.md CHANGED
@@ -67,8 +67,12 @@ Creates an `InkView` instance and initializes the wasm runtime internally.
67
67
  - Required
68
68
  - The logical width of the Ink view
69
69
  - `options.height: number`
70
- - Required
71
- - The logical height of the Ink view
70
+ - Required in `bounded` mode
71
+ - Optional in `width-constrained-auto-height` mode
72
+ - `options.layoutMode?: 'bounded' | 'width-constrained-auto-height'`
73
+ - Optional
74
+ - Defaults to `bounded`
75
+ - Use `width-constrained-auto-height` when the host wants a fixed width and a runtime-driven height
72
76
  - `options.scaleFactor?: number`
73
77
  - Optional
74
78
  - The device pixel ratio, defaulting to `window.devicePixelRatio`
@@ -87,6 +91,7 @@ Creates an `InkView` instance and initializes the wasm runtime internally.
87
91
  - Creates the underlying `InkWebView`
88
92
  - Returns the higher-level `InkView` wrapper
89
93
  - Automatically calls `bindCanvas()` if a `canvas` is provided
94
+ - In auto-height mode, automatically adopts the latest runtime content height for HTML canvas surfaces
90
95
 
91
96
  **Returns**
92
97
 
@@ -94,6 +99,27 @@ Creates an `InkView` instance and initializes the wasm runtime internally.
94
99
  - Resolves to an `InkView` instance that can then call
95
100
  `bindDomEvents()`, `openBundle()`, and `openFromVfs()`
96
101
 
102
+ ### Auto-height Layout
103
+
104
+ Use `layoutMode: 'width-constrained-auto-height'` when the host controls width
105
+ but wants Ink to drive the rendered height:
106
+
107
+ ```ts
108
+ const view = await createInkView({
109
+ width: 360,
110
+ layoutMode: 'width-constrained-auto-height',
111
+ scaleFactor: window.devicePixelRatio,
112
+ canvas,
113
+ });
114
+ ```
115
+
116
+ In this mode:
117
+
118
+ - the host still owns the constrained width
119
+ - the SDK automatically adopts runtime-reported content height
120
+ - browser hosts should call `view.resize()` when width or device pixel ratio changes
121
+ - browser hosts do not need to manually apply HTML canvas height in the common case
122
+
97
123
  ### `configureNetwork(options)`
98
124
 
99
125
  Configures host-controlled request interception for Ink network traffic.
package/index.d.ts CHANGED
@@ -40,16 +40,61 @@ export interface InitInkOptions {
40
40
  export interface CreateInkViewOptions {
41
41
  /** Initial logical width in CSS pixels. */
42
42
  width: number;
43
- /** Initial logical height in CSS pixels. */
44
- height: number;
43
+ /** Initial logical height in CSS pixels. Required in `bounded` mode and optional in auto-height mode. */
44
+ height?: number;
45
+ /** Layout behavior used by the host surface. Defaults to `bounded`. */
46
+ layoutMode?: InkLayoutMode;
45
47
  /** Device pixel ratio override. Defaults to `window.devicePixelRatio` when available. */
46
48
  scaleFactor?: number;
47
- /** Optional canvas to bind immediately after creation. */
49
+ /** Legacy shortcut for immediately binding an HTML canvas after creation. */
48
50
  canvas?: HTMLCanvasElement;
51
+ /** Optional surface descriptor bound immediately after creation. */
52
+ surface?: InkSurfaceDescriptor | null;
53
+ /** Whether the internal render loop should start immediately after creation. */
54
+ autoRender?: boolean;
55
+ /** Whether `destroy()` should clear the currently attached surface. Defaults to `true`. */
56
+ clearOnDestroy?: boolean;
57
+ /** Callback fired after Ink reports a new measured content size. */
58
+ onContentSizeChanged?: InkContentSizeChangedHandler | null;
49
59
  /** Optional wasm bootstrap overrides. */
50
60
  wasm?: InitInkOptions;
51
61
  }
52
62
 
63
+ /** Cross-platform layout mode exposed by browser hosts. */
64
+ export type InkLayoutMode = 'bounded' | 'width-constrained-auto-height';
65
+
66
+ /** Measured content size reported by the Ink runtime in CSS pixels. */
67
+ export interface InkContentSize {
68
+ width: number;
69
+ height: number;
70
+ }
71
+
72
+ /** Surface descriptor for a DOM-backed HTML canvas target. */
73
+ export interface InkHtmlCanvasSurface {
74
+ type: 'html-canvas';
75
+ canvas: HTMLCanvasElement;
76
+ }
77
+
78
+ /**
79
+ * Surface descriptor for an OffscreenCanvas target.
80
+ *
81
+ * The current browser SDK supports this descriptor on the main thread by
82
+ * rendering into an internal backing `HTMLCanvasElement` and copying each
83
+ * presented frame into the target `OffscreenCanvas`.
84
+ *
85
+ * This means the host-facing `InkView` API already works with
86
+ * `offscreen-canvas`, but it is not yet a pure worker-only renderer path.
87
+ * Hosts that need a document-free OffscreenCanvas backend should treat that as
88
+ * a future capability.
89
+ */
90
+ export interface InkOffscreenCanvasSurface {
91
+ type: 'offscreen-canvas';
92
+ canvas: OffscreenCanvas;
93
+ }
94
+
95
+ /** Supported surface descriptors accepted by {@link InkView.attachSurface}. */
96
+ export type InkSurfaceDescriptor = InkHtmlCanvasSurface | InkOffscreenCanvasSurface;
97
+
53
98
  /**
54
99
  * Opens an in-memory Ink app bundle that is already available in the host.
55
100
  */
@@ -197,6 +242,8 @@ export interface InkHostMessageStream {
197
242
 
198
243
  /** Callback invoked after the runtime requests that the host close the current view. */
199
244
  export type InkCloseRequestedHandler = () => void;
245
+ /** Callback invoked after the runtime reports a new measured content size. */
246
+ export type InkContentSizeChangedHandler = (contentSize: InkContentSize) => void;
200
247
 
201
248
  /**
202
249
  * Initializes the browser SDK and ensures the wasm runtime is ready to create
@@ -255,7 +302,7 @@ export declare function loadBundleFromVfs(
255
302
  * A typical flow is:
256
303
  *
257
304
  * 1. Create a view with {@link InkView.create}.
258
- * 2. Bind a canvas and DOM events if needed.
305
+ * 2. Attach a surface and DOM events if needed.
259
306
  * 3. Open an in-memory bundle or load one from VFS.
260
307
  * 4. Render manually with {@link render} or start the internal loop with
261
308
  * {@link startRendering}.
@@ -271,11 +318,33 @@ export declare class InkView {
271
318
  */
272
319
  static create(options: CreateInkViewOptions): Promise<InkView>;
273
320
 
321
+ /**
322
+ * Attaches or reattaches the render surface used by this view.
323
+ *
324
+ * Hosts should prefer this over the legacy {@link bindCanvas} alias when
325
+ * adopting the `View + Surface + Runtime Control` API shape.
326
+ */
327
+ attachSurface(surface: InkSurfaceDescriptor): this;
328
+
329
+ /**
330
+ * Detaches the currently attached surface without destroying the view.
331
+ *
332
+ * When `options.clear` is not `false`, the host-visible surface is cleared
333
+ * before it is released from the view.
334
+ */
335
+ detachSurface(options?: { clear?: boolean }): this;
336
+
337
+ /** Returns the currently attached surface descriptor, if any. */
338
+ getSurface(): InkSurfaceDescriptor | null;
339
+
274
340
  /**
275
341
  * Binds or rebinds the canvas used for drawing the current view.
276
342
  *
277
343
  * Rebinding is useful when the host recreates a canvas element while keeping
278
344
  * the same Ink runtime instance alive.
345
+ *
346
+ * This is a legacy alias for
347
+ * `attachSurface({ type: 'html-canvas', canvas })`.
279
348
  */
280
349
  bindCanvas(canvas: HTMLCanvasElement): this;
281
350
 
@@ -321,11 +390,15 @@ export declare class InkView {
321
390
  /**
322
391
  * Resizes the logical surface and optionally updates the scale factor.
323
392
  *
324
- * Hosts should call this whenever the canvas size or device pixel ratio
325
- * changes.
393
+ * Hosts should call this whenever the constrained width or device pixel ratio
394
+ * changes. In `width-constrained-auto-height` mode, the SDK continues to
395
+ * adopt the runtime-reported height automatically after width-driven relayout.
326
396
  */
327
397
  resize(width: number, height: number, scaleFactor?: number): this;
328
398
 
399
+ /** Switches the active layout mode and forces the current page to re-layout. */
400
+ setLayoutMode(layoutMode: InkLayoutMode): this;
401
+
329
402
  /** Forwards a host focus event so the Ink instance can accept focus-dependent input. */
330
403
  focus(): this;
331
404
 
@@ -356,6 +429,20 @@ export declare class InkView {
356
429
  */
357
430
  notifyUserInteraction(): this;
358
431
 
432
+ /** Forwards a pointer-like event directly into the current Ink view. */
433
+ dispatchPointer(
434
+ eventType: string,
435
+ x: number,
436
+ y: number,
437
+ id?: number,
438
+ button?: number,
439
+ deltaX?: number,
440
+ deltaY?: number,
441
+ ): this;
442
+
443
+ /** Forwards a keyboard/input event directly into the current Ink view. */
444
+ dispatchInput(eventType: string, code: string, timestamp?: number): this;
445
+
359
446
  /**
360
447
  * Dispatches a one-shot host message to the current Ink page.
361
448
  *
@@ -396,21 +483,37 @@ export declare class InkView {
396
483
  /** Stops the internal animation/render loop started by {@link startRendering}. */
397
484
  stopRendering(): this;
398
485
 
399
- /** Returns whether the internal render loop is currently active. */
486
+ /** Returns whether the current app is still running and has not requested close. */
400
487
  isRunning(): boolean;
401
488
 
489
+ /** Returns whether the internal render loop is currently active. */
490
+ isRendering(): boolean;
491
+
492
+ /** Returns whether this host wrapper has already been destroyed. */
493
+ isDestroyed(): boolean;
494
+
402
495
  /**
403
496
  * Registers the callback fired after Ink requests that the host close this view.
404
497
  *
405
498
  * When close is requested, the SDK marks the view as close-requested, stops
406
- * the internal render loop automatically, and then invokes this callback.
499
+ * the internal render loop automatically, relies on the runtime to blank the
500
+ * currently attached surface, and then invokes this callback.
407
501
  * Pass `null` to clear the current callback.
408
502
  */
409
503
  setOnCloseRequested(callback: InkCloseRequestedHandler | null): this;
410
504
 
505
+ /** Property-style close callback preferred by the new SDK shape. */
506
+ onCloseRequested: InkCloseRequestedHandler | null;
507
+
411
508
  /** Returns whether Ink has already requested that the host close this view. */
412
509
  isCloseRequested(): boolean;
413
510
 
511
+ /** Registers the callback fired after Ink reports a new measured content size. */
512
+ setOnContentSizeChanged(callback: InkContentSizeChangedHandler | null): this;
513
+
514
+ /** Property-style content size callback preferred by the new SDK shape. */
515
+ onContentSizeChanged: InkContentSizeChangedHandler | null;
516
+
414
517
  /**
415
518
  * Releases the underlying wasm view and detaches associated host resources.
416
519
  *
package/index.js CHANGED
@@ -14,6 +14,20 @@ function getDefaultScaleFactor() {
14
14
  return Number(globalThis.devicePixelRatio || 1);
15
15
  }
16
16
 
17
+ function normalizeScaleFactor(value) {
18
+ const numericValue = Number(value);
19
+ if (Number.isFinite(numericValue) && numericValue > 0) {
20
+ return numericValue;
21
+ }
22
+
23
+ const defaultScaleFactor = getDefaultScaleFactor();
24
+ if (Number.isFinite(defaultScaleFactor) && defaultScaleFactor > 0) {
25
+ return defaultScaleFactor;
26
+ }
27
+
28
+ return 1;
29
+ }
30
+
17
31
  function ensureFetch(fetchImpl) {
18
32
  const resolved = fetchImpl || globalThis.fetch;
19
33
  if (typeof resolved !== 'function') {
@@ -250,9 +264,11 @@ function normalizeKeyboardCode(event) {
250
264
 
251
265
  function getPointerPosition(canvas, event) {
252
266
  const rect = canvas.getBoundingClientRect();
267
+ const scaleX = rect.width > 0 ? canvas.width / rect.width : 1;
268
+ const scaleY = rect.height > 0 ? canvas.height / rect.height : 1;
253
269
  return {
254
- x: event.clientX - rect.left,
255
- y: event.clientY - rect.top,
270
+ x: (event.clientX - rect.left) * scaleX,
271
+ y: (event.clientY - rect.top) * scaleY,
256
272
  };
257
273
  }
258
274
 
@@ -278,6 +294,20 @@ function ensureAnimationFrameApi() {
278
294
  };
279
295
  }
280
296
 
297
+ function createDomCanvas(width, height) {
298
+ const documentRef = globalThis.document;
299
+ if (!documentRef || typeof documentRef.createElement !== 'function') {
300
+ throw new Error(
301
+ 'OffscreenCanvas surfaces currently require a browser document to create a backing HTML canvas.',
302
+ );
303
+ }
304
+
305
+ const canvas = documentRef.createElement('canvas');
306
+ canvas.width = Math.max(1, Number(width) || 1);
307
+ canvas.height = Math.max(1, Number(height) || 1);
308
+ return canvas;
309
+ }
310
+
281
311
  function normalizeHostMessageMetadata(origin, lastEventId) {
282
312
  if (typeof origin !== 'string') {
283
313
  throw new TypeError('`origin` must be a string.');
@@ -313,6 +343,81 @@ function serializeHostMessagePayload(dataOrJson) {
313
343
  return payloadJson;
314
344
  }
315
345
 
346
+ function cloneSurfaceDescriptor(surface) {
347
+ if (!surface) {
348
+ return null;
349
+ }
350
+ return { ...surface };
351
+ }
352
+
353
+ function normalizeSurfaceDescriptor(surface) {
354
+ if (!surface) {
355
+ return null;
356
+ }
357
+
358
+ if (typeof surface !== 'object') {
359
+ throw new TypeError('`surface` must be an object.');
360
+ }
361
+
362
+ if (surface.type === 'html-canvas') {
363
+ if (!surface.canvas || typeof surface.canvas.getBoundingClientRect !== 'function') {
364
+ throw new TypeError('`surface.canvas` must be an HTMLCanvasElement-like object.');
365
+ }
366
+ return {
367
+ type: 'html-canvas',
368
+ canvas: surface.canvas,
369
+ };
370
+ }
371
+
372
+ if (surface.type === 'offscreen-canvas') {
373
+ if (!surface.canvas || typeof surface.canvas.getContext !== 'function') {
374
+ throw new TypeError('`surface.canvas` must be an OffscreenCanvas-like object.');
375
+ }
376
+ return {
377
+ type: 'offscreen-canvas',
378
+ canvas: surface.canvas,
379
+ };
380
+ }
381
+
382
+ throw new TypeError(`Unsupported surface type: ${String(surface.type)}`);
383
+ }
384
+
385
+ function normalizeLayoutMode(value) {
386
+ if (value == null || value === '') {
387
+ return 'bounded';
388
+ }
389
+ if (value === 'bounded' || value === 'width-constrained-auto-height') {
390
+ return value;
391
+ }
392
+ throw new TypeError('`layoutMode` must be either `bounded` or `width-constrained-auto-height`.');
393
+ }
394
+
395
+ function normalizeHostLanguageModelConfig(config) {
396
+ if (config == null) {
397
+ return null;
398
+ }
399
+ if (typeof config !== 'object') {
400
+ throw new TypeError('`config` must be an object or null.');
401
+ }
402
+
403
+ const headers =
404
+ config.headers && typeof config.headers === 'object' && !Array.isArray(config.headers)
405
+ ? Object.fromEntries(
406
+ Object.entries(config.headers).map(([key, value]) => [String(key), String(value)]),
407
+ )
408
+ : {};
409
+
410
+ return {
411
+ endpoint: String(config.endpoint || '').trim(),
412
+ defaultModel: config.defaultModel == null ? null : String(config.defaultModel).trim(),
413
+ apiStyle: String(config.apiStyle || '').trim(),
414
+ headers,
415
+ shareVendorHeaders: Boolean(config.shareVendorHeaders),
416
+ vendorHeadersEnv:
417
+ config.vendorHeadersEnv == null ? null : String(config.vendorHeadersEnv).trim(),
418
+ };
419
+ }
420
+
316
421
  class InkHostMessageStream {
317
422
  #rawStream;
318
423
  #requestRender;
@@ -369,22 +474,31 @@ export class InkView {
369
474
  static async create(options) {
370
475
  const config = options || {};
371
476
  const width = Number(config.width);
477
+ const layoutMode = normalizeLayoutMode(config.layoutMode);
372
478
  const height = Number(config.height);
479
+ const scaleFactor = normalizeScaleFactor(config.scaleFactor);
373
480
 
374
- if (!Number.isFinite(width) || !Number.isFinite(height)) {
375
- throw new Error('`width` and `height` are required numeric values.');
481
+ if (!Number.isFinite(width)) {
482
+ throw new Error('`width` is a required numeric value.');
483
+ }
484
+ if (layoutMode === 'bounded' && !Number.isFinite(height)) {
485
+ throw new Error('`height` is required when `layoutMode` is `bounded`.');
376
486
  }
487
+ const initialHeight =
488
+ layoutMode === 'width-constrained-auto-height' && !Number.isFinite(height) ? 1 : height;
377
489
 
378
490
  const bindings = await initInk(config.wasm);
379
- const rawView = new bindings.InkWebView(
380
- width,
381
- height,
382
- Number(config.scaleFactor || getDefaultScaleFactor()),
383
- );
491
+ const physicalWidth = Math.max(1, Math.round(width * scaleFactor));
492
+ const physicalHeight = Math.max(1, Math.round(initialHeight * scaleFactor));
493
+ const rawView = new bindings.InkWebView(physicalWidth, physicalHeight, scaleFactor, layoutMode);
384
494
  const view = new InkView(rawView, config);
385
-
386
- if (config.canvas) {
387
- view.bindCanvas(config.canvas);
495
+ const initialSurface =
496
+ config.surface || (config.canvas ? { type: 'html-canvas', canvas: config.canvas } : null);
497
+ if (initialSurface) {
498
+ view.attachSurface(initialSurface);
499
+ }
500
+ if (config.autoRender) {
501
+ view.startRendering();
388
502
  }
389
503
 
390
504
  return view;
@@ -392,6 +506,7 @@ export class InkView {
392
506
 
393
507
  #rawView;
394
508
  #canvas;
509
+ #surface;
395
510
  #animationFrameApi;
396
511
  #frameHandle;
397
512
  #autoRender;
@@ -399,10 +514,20 @@ export class InkView {
399
514
  #destroyed;
400
515
  #domCleanup;
401
516
  #onCloseRequested;
517
+ #clearOnDestroy;
518
+ #logicalWidth;
519
+ #logicalHeight;
520
+ #boundedHeight;
521
+ #layoutMode;
522
+ #latestContentSize;
523
+ #scaleFactor;
524
+ #surfaceBinding;
525
+ #onContentSizeChanged;
402
526
 
403
527
  constructor(rawView, options = {}) {
404
528
  this.#rawView = rawView;
405
529
  this.#canvas = options.canvas || null;
530
+ this.#surface = null;
406
531
  this.#animationFrameApi = ensureAnimationFrameApi();
407
532
  this.#frameHandle = null;
408
533
  this.#autoRender = false;
@@ -410,6 +535,225 @@ export class InkView {
410
535
  this.#destroyed = false;
411
536
  this.#domCleanup = null;
412
537
  this.#onCloseRequested = null;
538
+ this.#clearOnDestroy = options.clearOnDestroy !== false;
539
+ this.#logicalWidth = Number(options.width) || 1;
540
+ this.#logicalHeight = Number(options.height) || 1;
541
+ this.#boundedHeight = Number(options.height) || 1;
542
+ this.#layoutMode = normalizeLayoutMode(options.layoutMode);
543
+ this.#latestContentSize = null;
544
+ this.#scaleFactor = normalizeScaleFactor(options.scaleFactor);
545
+ this.#surfaceBinding = null;
546
+ this.#onContentSizeChanged = null;
547
+ this.onContentSizeChanged = options.onContentSizeChanged || null;
548
+ }
549
+
550
+ #clearSurfaceContents() {
551
+ const clearTarget = (target) => {
552
+ if (!target || typeof target.getContext !== 'function') {
553
+ return;
554
+ }
555
+
556
+ const context = target.getContext('2d');
557
+ if (!context || typeof context.clearRect !== 'function') {
558
+ return;
559
+ }
560
+
561
+ if (typeof context.save === 'function') {
562
+ context.save();
563
+ }
564
+ if (typeof context.setTransform === 'function') {
565
+ context.setTransform(1, 0, 0, 1, 0, 0);
566
+ } else if (typeof context.resetTransform === 'function') {
567
+ context.resetTransform();
568
+ }
569
+ context.clearRect(0, 0, Number(target.width) || 0, Number(target.height) || 0);
570
+ if (typeof context.restore === 'function') {
571
+ context.restore();
572
+ }
573
+ };
574
+
575
+ clearTarget(this.#canvas);
576
+ if (this.#surfaceBinding?.type === 'offscreen-canvas') {
577
+ clearTarget(this.#surfaceBinding.targetCanvas);
578
+ }
579
+ }
580
+
581
+ #syncSurfaceBindingSize(width, height) {
582
+ if (!this.#surfaceBinding || this.#surfaceBinding.type !== 'offscreen-canvas') {
583
+ return;
584
+ }
585
+
586
+ const nextWidth = Math.max(1, Number(width) || 1);
587
+ const nextHeight = Math.max(1, Number(height) || 1);
588
+ const nextBitmapWidth = Math.max(1, Math.round(nextWidth * this.#scaleFactor));
589
+ const nextBitmapHeight = Math.max(1, Math.round(nextHeight * this.#scaleFactor));
590
+ this.#surfaceBinding.backingCanvas.width = nextBitmapWidth;
591
+ this.#surfaceBinding.backingCanvas.height = nextBitmapHeight;
592
+ this.#surfaceBinding.targetCanvas.width = nextBitmapWidth;
593
+ this.#surfaceBinding.targetCanvas.height = nextBitmapHeight;
594
+ }
595
+
596
+ #syncHtmlCanvasBindingSize(width, height, options = {}) {
597
+ if (!this.#surfaceBinding || this.#surfaceBinding.type !== 'html-canvas') {
598
+ return false;
599
+ }
600
+
601
+ const nextWidth = Math.max(1, Number(width) || 1);
602
+ const nextHeight = Math.max(1, Number(height) || 1);
603
+ const nextBitmapWidth = Math.max(1, Math.round(nextWidth * this.#scaleFactor));
604
+ const nextBitmapHeight = Math.max(1, Math.round(nextHeight * this.#scaleFactor));
605
+ const canvas = this.#surfaceBinding.canvas;
606
+ let changed = false;
607
+
608
+ if (Number(canvas.width) !== nextBitmapWidth) {
609
+ canvas.width = nextBitmapWidth;
610
+ changed = true;
611
+ }
612
+ if (Number(canvas.height) !== nextBitmapHeight) {
613
+ canvas.height = nextBitmapHeight;
614
+ changed = true;
615
+ }
616
+
617
+ if (options.updateStyleWidth && canvas.style?.width !== `${nextWidth}px`) {
618
+ canvas.style.width = `${nextWidth}px`;
619
+ changed = true;
620
+ }
621
+
622
+ if (options.updateStyleHeight && canvas.style?.height !== `${nextHeight}px`) {
623
+ canvas.style.height = `${nextHeight}px`;
624
+ changed = true;
625
+ }
626
+
627
+ if (options.updateContainerWidth && canvas.parentElement?.style?.width !== `${nextWidth}px`) {
628
+ canvas.parentElement.style.width = `${nextWidth}px`;
629
+ changed = true;
630
+ }
631
+
632
+ if (options.updateContainerHeight && canvas.parentElement?.style?.height !== 'auto') {
633
+ canvas.parentElement.style.height = 'auto';
634
+ changed = true;
635
+ }
636
+
637
+ return changed;
638
+ }
639
+
640
+ #syncHtmlCanvasAutoHeight(contentSize) {
641
+ if (this.#layoutMode !== 'width-constrained-auto-height') {
642
+ return false;
643
+ }
644
+ if (!this.#surfaceBinding || this.#surfaceBinding.type !== 'html-canvas') {
645
+ return false;
646
+ }
647
+
648
+ const nextHeight = Math.max(1, Number(contentSize?.height) || 1);
649
+ const adopted = this.#syncHtmlCanvasBindingSize(this.#logicalWidth, nextHeight, {
650
+ updateStyleWidth: true,
651
+ updateStyleHeight: true,
652
+ updateContainerWidth: true,
653
+ updateContainerHeight: true,
654
+ });
655
+
656
+ if (!adopted && this.#logicalHeight === nextHeight) {
657
+ return false;
658
+ }
659
+
660
+ this.#logicalHeight = nextHeight;
661
+ this.#syncRawViewSize(this.#logicalWidth, nextHeight);
662
+ return true;
663
+ }
664
+
665
+ #physicalWidth() {
666
+ return Math.max(1, Math.round(this.#logicalWidth * this.#scaleFactor));
667
+ }
668
+
669
+ #physicalHeight(height = this.#logicalHeight) {
670
+ return Math.max(1, Math.round((Number(height) || 1) * this.#scaleFactor));
671
+ }
672
+
673
+ #syncRawViewSize(width = this.#logicalWidth, height = this.#logicalHeight) {
674
+ if (typeof this.#rawView.resize !== 'function') {
675
+ return;
676
+ }
677
+ this.#rawView.resize(
678
+ Math.max(1, Math.round((Number(width) || 1) * this.#scaleFactor)),
679
+ Math.max(1, Math.round((Number(height) || 1) * this.#scaleFactor)),
680
+ this.#scaleFactor,
681
+ );
682
+ }
683
+
684
+ #currentContentSize() {
685
+ if (
686
+ typeof this.#rawView.currentContentWidth !== 'function' ||
687
+ typeof this.#rawView.currentContentHeight !== 'function'
688
+ ) {
689
+ return null;
690
+ }
691
+ const width = Number(this.#rawView.currentContentWidth());
692
+ const height = Number(this.#rawView.currentContentHeight());
693
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width < 0 || height < 0) {
694
+ return null;
695
+ }
696
+ return { width, height };
697
+ }
698
+
699
+ #consumeContentSizeChanged() {
700
+ if (typeof this.#rawView.consumeContentSizeChanged !== 'function') {
701
+ return false;
702
+ }
703
+ if (!this.#rawView.consumeContentSizeChanged()) {
704
+ return false;
705
+ }
706
+
707
+ const contentSize = this.#currentContentSize();
708
+ if (!contentSize) {
709
+ return false;
710
+ }
711
+ this.#latestContentSize = contentSize;
712
+ this.#syncHtmlCanvasAutoHeight(contentSize);
713
+ if (typeof this.#onContentSizeChanged === 'function') {
714
+ this.#onContentSizeChanged(contentSize);
715
+ }
716
+ return true;
717
+ }
718
+
719
+ #presentSurface() {
720
+ if (!this.#surfaceBinding || this.#surfaceBinding.type !== 'offscreen-canvas') {
721
+ return;
722
+ }
723
+
724
+ const { backingCanvas, targetCanvas } = this.#surfaceBinding;
725
+ const context = targetCanvas.getContext('2d');
726
+ if (
727
+ !context ||
728
+ typeof context.clearRect !== 'function' ||
729
+ typeof context.drawImage !== 'function'
730
+ ) {
731
+ return;
732
+ }
733
+
734
+ if (typeof context.save === 'function') {
735
+ context.save();
736
+ }
737
+ if (typeof context.setTransform === 'function') {
738
+ context.setTransform(1, 0, 0, 1, 0, 0);
739
+ } else if (typeof context.resetTransform === 'function') {
740
+ context.resetTransform();
741
+ }
742
+ context.clearRect(0, 0, Number(targetCanvas.width) || 0, Number(targetCanvas.height) || 0);
743
+ context.drawImage(
744
+ backingCanvas,
745
+ 0,
746
+ 0,
747
+ Number(backingCanvas.width) || 0,
748
+ Number(backingCanvas.height) || 0,
749
+ 0,
750
+ 0,
751
+ Number(targetCanvas.width) || 0,
752
+ Number(targetCanvas.height) || 0,
753
+ );
754
+ if (typeof context.restore === 'function') {
755
+ context.restore();
756
+ }
413
757
  }
414
758
 
415
759
  #resetCloseRequestedState() {
@@ -435,16 +779,67 @@ export class InkView {
435
779
  return true;
436
780
  }
437
781
 
438
- bindCanvas(canvas) {
439
- if (!canvas || typeof canvas.getBoundingClientRect !== 'function') {
440
- throw new TypeError('`canvas` must be an HTMLCanvasElement-like object.');
782
+ attachSurface(surface) {
783
+ const normalizedSurface = normalizeSurfaceDescriptor(surface);
784
+ if (!normalizedSurface) {
785
+ throw new TypeError('`surface` must be provided.');
786
+ }
787
+
788
+ if (normalizedSurface.type === 'html-canvas') {
789
+ this.#rawView.bindCanvas(normalizedSurface.canvas);
790
+ this.#surfaceBinding = {
791
+ type: 'html-canvas',
792
+ canvas: normalizedSurface.canvas,
793
+ };
794
+ this.#surface = normalizedSurface;
795
+ this.#canvas = normalizedSurface.canvas;
796
+ this.#syncRawViewSize();
797
+ if (this.#layoutMode === 'width-constrained-auto-height') {
798
+ this.#syncHtmlCanvasAutoHeight(this.#latestContentSize || { height: this.#logicalHeight });
799
+ }
800
+ return this;
801
+ }
802
+
803
+ const backingCanvas = createDomCanvas(this.#physicalWidth(), this.#physicalHeight());
804
+ this.#rawView.bindCanvas(backingCanvas);
805
+ this.#surfaceBinding = {
806
+ type: 'offscreen-canvas',
807
+ backingCanvas,
808
+ targetCanvas: normalizedSurface.canvas,
809
+ };
810
+ this.#surface = normalizedSurface;
811
+ this.#canvas = backingCanvas;
812
+ this.#syncRawViewSize();
813
+ this.#syncSurfaceBindingSize(this.#logicalWidth, this.#logicalHeight);
814
+ this.#presentSurface();
815
+ return this;
816
+ }
817
+
818
+ detachSurface(options = {}) {
819
+ if (!this.#surface && !this.#canvas) {
820
+ return this;
441
821
  }
442
822
 
443
- this.#rawView.bindCanvas(canvas);
444
- this.#canvas = canvas;
823
+ if (options.clear !== false) {
824
+ this.#clearSurfaceContents();
825
+ }
826
+ if (typeof this.#rawView.clearSurface === 'function') {
827
+ this.#rawView.clearSurface();
828
+ }
829
+ this.#surfaceBinding = null;
830
+ this.#surface = null;
831
+ this.#canvas = null;
445
832
  return this;
446
833
  }
447
834
 
835
+ getSurface() {
836
+ return cloneSurfaceDescriptor(this.#surface);
837
+ }
838
+
839
+ bindCanvas(canvas) {
840
+ return this.attachSurface({ type: 'html-canvas', canvas });
841
+ }
842
+
448
843
  bindDomEvents(options = {}) {
449
844
  const canvas = options.canvas || this.#canvas;
450
845
  if (!canvas) {
@@ -470,6 +865,16 @@ export class InkView {
470
865
  focusTarget.setAttribute('tabindex', '0');
471
866
  }
472
867
 
868
+ const scaleWheelDelta = (event) => {
869
+ const rect = canvas.getBoundingClientRect();
870
+ const scaleX = rect.width > 0 ? canvas.width / rect.width : this.#scaleFactor;
871
+ const scaleY = rect.height > 0 ? canvas.height / rect.height : this.#scaleFactor;
872
+ return {
873
+ deltaX: (event.deltaX || 0) * scaleX,
874
+ deltaY: (event.deltaY || 0) * scaleY,
875
+ };
876
+ };
877
+
473
878
  addListener(canvas, 'pointerdown', (event) => {
474
879
  const { x, y } = getPointerPosition(canvas, event);
475
880
  this.notifyUserInteraction();
@@ -531,18 +936,11 @@ export class InkView {
531
936
  'wheel',
532
937
  (event) => {
533
938
  const { x, y } = getPointerPosition(canvas, event);
939
+ const { deltaX, deltaY } = scaleWheelDelta(event);
534
940
  if (options.preventWheelDefault !== false && typeof event.preventDefault === 'function') {
535
941
  event.preventDefault();
536
942
  }
537
- this.#rawView.dispatchPointer(
538
- 'mousewheel',
539
- x,
540
- y,
541
- 0,
542
- 0,
543
- event.deltaX || 0,
544
- event.deltaY || 0,
545
- );
943
+ this.#rawView.dispatchPointer('mousewheel', x, y, 0, 0, deltaX, deltaY);
546
944
  this.requestRender();
547
945
  },
548
946
  { passive: false },
@@ -640,7 +1038,67 @@ export class InkView {
640
1038
  }
641
1039
 
642
1040
  resize(width, height, scaleFactor = getDefaultScaleFactor()) {
643
- this.#rawView.resize(Number(width), Number(height), Number(scaleFactor));
1041
+ const nextWidth = Math.max(1, Number(width) || 1);
1042
+ const fallbackHeight =
1043
+ this.#layoutMode === 'width-constrained-auto-height'
1044
+ ? this.#logicalHeight
1045
+ : this.#boundedHeight;
1046
+ const nextHeight = Math.max(1, Number(height) || fallbackHeight || 1);
1047
+ this.#logicalWidth = nextWidth;
1048
+ this.#logicalHeight = nextHeight;
1049
+ if (this.#layoutMode === 'bounded') {
1050
+ this.#boundedHeight = nextHeight;
1051
+ }
1052
+ this.#scaleFactor = normalizeScaleFactor(scaleFactor);
1053
+ this.#syncRawViewSize();
1054
+ if (this.#surfaceBinding?.type === 'html-canvas') {
1055
+ this.#syncHtmlCanvasBindingSize(this.#logicalWidth, this.#logicalHeight, {
1056
+ updateStyleWidth: true,
1057
+ updateStyleHeight: this.#layoutMode === 'width-constrained-auto-height',
1058
+ updateContainerWidth: true,
1059
+ updateContainerHeight: this.#layoutMode === 'width-constrained-auto-height',
1060
+ });
1061
+ } else {
1062
+ this.#syncSurfaceBindingSize(this.#logicalWidth, this.#logicalHeight);
1063
+ }
1064
+ this.#presentSurface();
1065
+ this.requestRender();
1066
+ return this;
1067
+ }
1068
+
1069
+ setLayoutMode(layoutMode) {
1070
+ const nextLayoutMode = normalizeLayoutMode(layoutMode);
1071
+ if (this.#layoutMode === nextLayoutMode) {
1072
+ return this;
1073
+ }
1074
+
1075
+ const currentContentSize = this.#currentContentSize();
1076
+ this.#layoutMode = nextLayoutMode;
1077
+ this.#latestContentSize = currentContentSize;
1078
+ this.#rawView.setLayoutMode(nextLayoutMode);
1079
+
1080
+ if (nextLayoutMode === 'bounded') {
1081
+ this.#logicalHeight = this.#boundedHeight;
1082
+ this.#syncRawViewSize();
1083
+ if (this.#surfaceBinding?.type === 'html-canvas') {
1084
+ this.#syncHtmlCanvasBindingSize(this.#logicalWidth, this.#logicalHeight);
1085
+ } else {
1086
+ this.#syncSurfaceBindingSize(this.#logicalWidth, this.#logicalHeight);
1087
+ }
1088
+ } else if (currentContentSize) {
1089
+ this.#syncHtmlCanvasAutoHeight(currentContentSize);
1090
+ } else {
1091
+ this.#syncRawViewSize();
1092
+ if (this.#surfaceBinding?.type === 'html-canvas') {
1093
+ this.#syncHtmlCanvasBindingSize(this.#logicalWidth, this.#logicalHeight, {
1094
+ updateStyleWidth: true,
1095
+ updateStyleHeight: true,
1096
+ updateContainerWidth: true,
1097
+ updateContainerHeight: true,
1098
+ });
1099
+ }
1100
+ }
1101
+
644
1102
  this.requestRender();
645
1103
  return this;
646
1104
  }
@@ -669,6 +1127,29 @@ export class InkView {
669
1127
  return this;
670
1128
  }
671
1129
 
1130
+ setHostLanguageModelConfig(config) {
1131
+ if (typeof this.#rawView.setLanguageModelConfig !== 'function') {
1132
+ return this;
1133
+ }
1134
+ const normalizedConfig = normalizeHostLanguageModelConfig(config);
1135
+ this.#rawView.setLanguageModelConfig(
1136
+ normalizedConfig == null ? null : JSON.stringify(normalizedConfig),
1137
+ );
1138
+ return this;
1139
+ }
1140
+
1141
+ dispatchPointer(eventType, x, y, id = 0, button = 0, deltaX = 0, deltaY = 0) {
1142
+ this.#rawView.dispatchPointer(eventType, x, y, id, button, deltaX, deltaY);
1143
+ this.requestRender();
1144
+ return this;
1145
+ }
1146
+
1147
+ dispatchInput(eventType, code, timestamp = Date.now()) {
1148
+ this.#rawView.dispatchInput(eventType, code, Number(timestamp));
1149
+ this.requestRender();
1150
+ return this;
1151
+ }
1152
+
672
1153
  dispatchMessageEvent(dataOrJson, origin = 'host', lastEventId = '') {
673
1154
  const metadata = normalizeHostMessageMetadata(origin, lastEventId);
674
1155
  this.#rawView.dispatchMessageEvent(
@@ -693,8 +1174,10 @@ export class InkView {
693
1174
  return false;
694
1175
  }
695
1176
  const hasMoreWork = Boolean(this.#rawView.render());
1177
+ const contentSizeChanged = this.#consumeContentSizeChanged();
1178
+ this.#presentSurface();
696
1179
  const closeRequested = this.#consumeCloseRequested();
697
- if (!closeRequested && (hasMoreWork || this.#autoRender)) {
1180
+ if (!closeRequested && (hasMoreWork || contentSizeChanged || this.#autoRender)) {
698
1181
  this.requestRender();
699
1182
  }
700
1183
  return !closeRequested && hasMoreWork;
@@ -737,14 +1220,52 @@ export class InkView {
737
1220
  return !this.#closeRequested && Boolean(this.#rawView.isRunning());
738
1221
  }
739
1222
 
1223
+ isDestroyed() {
1224
+ return this.#destroyed;
1225
+ }
1226
+
1227
+ isRendering() {
1228
+ return this.#autoRender;
1229
+ }
1230
+
740
1231
  setOnCloseRequested(callback) {
1232
+ if (callback != null && typeof callback !== 'function') {
1233
+ throw new TypeError('`callback` must be a function or null.');
1234
+ }
1235
+ this.onCloseRequested = callback || null;
1236
+ return this;
1237
+ }
1238
+
1239
+ get onCloseRequested() {
1240
+ return this.#onCloseRequested;
1241
+ }
1242
+
1243
+ set onCloseRequested(callback) {
741
1244
  if (callback != null && typeof callback !== 'function') {
742
1245
  throw new TypeError('`callback` must be a function or null.');
743
1246
  }
744
1247
  this.#onCloseRequested = callback || null;
1248
+ }
1249
+
1250
+ setOnContentSizeChanged(callback) {
1251
+ if (callback != null && typeof callback !== 'function') {
1252
+ throw new TypeError('`callback` must be a function or null.');
1253
+ }
1254
+ this.onContentSizeChanged = callback || null;
745
1255
  return this;
746
1256
  }
747
1257
 
1258
+ get onContentSizeChanged() {
1259
+ return this.#onContentSizeChanged;
1260
+ }
1261
+
1262
+ set onContentSizeChanged(callback) {
1263
+ if (callback != null && typeof callback !== 'function') {
1264
+ throw new TypeError('`callback` must be a function or null.');
1265
+ }
1266
+ this.#onContentSizeChanged = callback || null;
1267
+ }
1268
+
748
1269
  isCloseRequested() {
749
1270
  return this.#closeRequested;
750
1271
  }
@@ -755,9 +1276,18 @@ export class InkView {
755
1276
  }
756
1277
  this.#destroyed = true;
757
1278
  this.stopRendering();
1279
+ if (this.#clearOnDestroy) {
1280
+ this.#clearSurfaceContents();
1281
+ }
758
1282
  if (this.#domCleanup) {
759
1283
  this.#domCleanup();
760
1284
  }
1285
+ if (typeof this.#rawView.clearSurface === 'function') {
1286
+ this.#rawView.clearSurface();
1287
+ }
1288
+ this.#surfaceBinding = null;
1289
+ this.#surface = null;
1290
+ this.#canvas = null;
761
1291
  this.#rawView.destroy();
762
1292
  }
763
1293
  }
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "access": "public",
11
11
  "registry": "https://registry.npmjs.com/"
12
12
  },
13
- "version": "0.8.0",
13
+ "version": "0.9.1",
14
14
  "type": "module",
15
15
  "main": "index.js",
16
16
  "types": "index.d.ts",
package/pkg/ink_web.d.ts CHANGED
@@ -14,8 +14,12 @@ export class InkWebView {
14
14
  [Symbol.dispose](): void;
15
15
  bindCanvas(canvas: HTMLCanvasElement): void;
16
16
  blur(): void;
17
+ clearSurface(): void;
17
18
  consumeCloseRequested(): boolean;
19
+ consumeContentSizeChanged(): boolean;
18
20
  createMessageStream(origin: string, last_event_id: string): InkWebMessageStream;
21
+ currentContentHeight(): number;
22
+ currentContentWidth(): number;
19
23
  destroy(): void;
20
24
  dispatchInput(event_type: string, code: string, timestamp: number): void;
21
25
  dispatchMessageEvent(payload_json: string, origin: string, last_event_id: string): void;
@@ -23,13 +27,15 @@ export class InkWebView {
23
27
  focus(): void;
24
28
  isInteractive(): boolean;
25
29
  isRunning(): boolean;
26
- constructor(width: number, height: number, scale_factor: number);
30
+ constructor(width: number, height: number, scale_factor: number, layout_mode: string);
27
31
  notifyUserInteraction(): void;
28
32
  open(path: string, initial_page?: string | null, query_json?: string | null): void;
29
33
  openBundle(app_id: string, files: Map<any, any>, initial_page?: string | null, query_json?: string | null): void;
30
34
  render(): boolean;
31
35
  resize(width: number, height: number, scale_factor: number): void;
32
36
  setInteractive(interactive: boolean): void;
37
+ setLanguageModelConfig(config_json?: string | null): void;
38
+ setLayoutMode(layout_mode: string): void;
33
39
  }
34
40
 
35
41
  export function get_version(): string;
@@ -47,8 +53,12 @@ export interface InitOutput {
47
53
  readonly inkwebmessagestream_write: (a: number, b: number, c: number, d: number) => void;
48
54
  readonly inkwebview_bindCanvas: (a: number, b: number, c: number) => void;
49
55
  readonly inkwebview_blur: (a: number) => void;
56
+ readonly inkwebview_clearSurface: (a: number) => void;
50
57
  readonly inkwebview_consumeCloseRequested: (a: number) => number;
58
+ readonly inkwebview_consumeContentSizeChanged: (a: number) => number;
51
59
  readonly inkwebview_createMessageStream: (a: number, b: number, c: number, d: number, e: number) => number;
60
+ readonly inkwebview_currentContentHeight: (a: number) => number;
61
+ readonly inkwebview_currentContentWidth: (a: number) => number;
52
62
  readonly inkwebview_destroy: (a: number) => void;
53
63
  readonly inkwebview_dispatchInput: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
54
64
  readonly inkwebview_dispatchMessageEvent: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
@@ -56,19 +66,21 @@ export interface InitOutput {
56
66
  readonly inkwebview_focus: (a: number) => void;
57
67
  readonly inkwebview_isInteractive: (a: number) => number;
58
68
  readonly inkwebview_isRunning: (a: number) => number;
59
- readonly inkwebview_new: (a: number, b: number, c: number) => number;
69
+ readonly inkwebview_new: (a: number, b: number, c: number, d: number, e: number) => number;
60
70
  readonly inkwebview_notifyUserInteraction: (a: number) => void;
61
71
  readonly inkwebview_open: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
62
72
  readonly inkwebview_openBundle: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
63
73
  readonly inkwebview_render: (a: number, b: number) => void;
64
74
  readonly inkwebview_resize: (a: number, b: number, c: number, d: number) => void;
65
75
  readonly inkwebview_setInteractive: (a: number, b: number) => void;
76
+ readonly inkwebview_setLanguageModelConfig: (a: number, b: number, c: number, d: number) => void;
77
+ readonly inkwebview_setLayoutMode: (a: number, b: number, c: number) => void;
66
78
  readonly main: () => void;
67
- readonly __wasm_bindgen_func_elem_9308: (a: number, b: number) => void;
68
- readonly __wasm_bindgen_func_elem_13493: (a: number, b: number) => void;
69
- readonly __wasm_bindgen_func_elem_9474: (a: number, b: number, c: number) => void;
70
- readonly __wasm_bindgen_func_elem_13494: (a: number, b: number, c: number) => void;
71
- readonly __wasm_bindgen_func_elem_9475: (a: number, b: number) => void;
79
+ readonly __wasm_bindgen_func_elem_9470: (a: number, b: number) => void;
80
+ readonly __wasm_bindgen_func_elem_13736: (a: number, b: number) => void;
81
+ readonly __wasm_bindgen_func_elem_9754: (a: number, b: number, c: number) => void;
82
+ readonly __wasm_bindgen_func_elem_13737: (a: number, b: number, c: number) => void;
83
+ readonly __wasm_bindgen_func_elem_9755: (a: number, b: number) => void;
72
84
  readonly __wbindgen_export: (a: number, b: number) => number;
73
85
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
74
86
  readonly __wbindgen_export3: (a: number) => void;
package/pkg/ink_web.js CHANGED
@@ -72,6 +72,9 @@ export class InkWebView {
72
72
  blur() {
73
73
  wasm.inkwebview_blur(this.__wbg_ptr);
74
74
  }
75
+ clearSurface() {
76
+ wasm.inkwebview_clearSurface(this.__wbg_ptr);
77
+ }
75
78
  /**
76
79
  * @returns {boolean}
77
80
  */
@@ -79,6 +82,13 @@ export class InkWebView {
79
82
  const ret = wasm.inkwebview_consumeCloseRequested(this.__wbg_ptr);
80
83
  return ret !== 0;
81
84
  }
85
+ /**
86
+ * @returns {boolean}
87
+ */
88
+ consumeContentSizeChanged() {
89
+ const ret = wasm.inkwebview_consumeContentSizeChanged(this.__wbg_ptr);
90
+ return ret !== 0;
91
+ }
82
92
  /**
83
93
  * @param {string} origin
84
94
  * @param {string} last_event_id
@@ -92,6 +102,20 @@ export class InkWebView {
92
102
  const ret = wasm.inkwebview_createMessageStream(this.__wbg_ptr, ptr0, len0, ptr1, len1);
93
103
  return InkWebMessageStream.__wrap(ret);
94
104
  }
105
+ /**
106
+ * @returns {number}
107
+ */
108
+ currentContentHeight() {
109
+ const ret = wasm.inkwebview_currentContentHeight(this.__wbg_ptr);
110
+ return ret;
111
+ }
112
+ /**
113
+ * @returns {number}
114
+ */
115
+ currentContentWidth() {
116
+ const ret = wasm.inkwebview_currentContentWidth(this.__wbg_ptr);
117
+ return ret;
118
+ }
95
119
  destroy() {
96
120
  wasm.inkwebview_destroy(this.__wbg_ptr);
97
121
  }
@@ -186,9 +210,12 @@ export class InkWebView {
186
210
  * @param {number} width
187
211
  * @param {number} height
188
212
  * @param {number} scale_factor
213
+ * @param {string} layout_mode
189
214
  */
190
- constructor(width, height, scale_factor) {
191
- const ret = wasm.inkwebview_new(width, height, scale_factor);
215
+ constructor(width, height, scale_factor, layout_mode) {
216
+ const ptr0 = passStringToWasm0(layout_mode, wasm.__wbindgen_export, wasm.__wbindgen_export2);
217
+ const len0 = WASM_VECTOR_LEN;
218
+ const ret = wasm.inkwebview_new(width, height, scale_factor, ptr0, len0);
192
219
  this.__wbg_ptr = ret >>> 0;
193
220
  InkWebViewFinalization.register(this, this.__wbg_ptr, this);
194
221
  return this;
@@ -277,6 +304,32 @@ export class InkWebView {
277
304
  setInteractive(interactive) {
278
305
  wasm.inkwebview_setInteractive(this.__wbg_ptr, interactive);
279
306
  }
307
+ /**
308
+ * @param {string | null} [config_json]
309
+ */
310
+ setLanguageModelConfig(config_json) {
311
+ try {
312
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
313
+ var ptr0 = isLikeNone(config_json) ? 0 : passStringToWasm0(config_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
314
+ var len0 = WASM_VECTOR_LEN;
315
+ wasm.inkwebview_setLanguageModelConfig(retptr, this.__wbg_ptr, ptr0, len0);
316
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
317
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
318
+ if (r1) {
319
+ throw takeObject(r0);
320
+ }
321
+ } finally {
322
+ wasm.__wbindgen_add_to_stack_pointer(16);
323
+ }
324
+ }
325
+ /**
326
+ * @param {string} layout_mode
327
+ */
328
+ setLayoutMode(layout_mode) {
329
+ const ptr0 = passStringToWasm0(layout_mode, wasm.__wbindgen_export, wasm.__wbindgen_export2);
330
+ const len0 = WASM_VECTOR_LEN;
331
+ wasm.inkwebview_setLayoutMode(this.__wbg_ptr, ptr0, len0);
332
+ }
280
333
  }
281
334
  if (Symbol.dispose) InkWebView.prototype[Symbol.dispose] = InkWebView.prototype.free;
282
335
 
@@ -1094,28 +1147,28 @@ function __wbg_get_imports() {
1094
1147
  return ret;
1095
1148
  },
1096
1149
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
1097
- // Cast intrinsic for `Closure(Closure { dtor_idx: 2519, function: Function { arguments: [NamedExternref("CloseEvent")], shim_idx: 2472, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1098
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9308, __wasm_bindgen_func_elem_9474);
1150
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 2522, function: Function { arguments: [NamedExternref("CloseEvent")], shim_idx: 2526, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1151
+ const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9470, __wasm_bindgen_func_elem_9754);
1099
1152
  return addHeapObject(ret);
1100
1153
  },
1101
1154
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
1102
- // Cast intrinsic for `Closure(Closure { dtor_idx: 2519, function: Function { arguments: [NamedExternref("Event")], shim_idx: 2472, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1103
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9308, __wasm_bindgen_func_elem_9474);
1155
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 2522, function: Function { arguments: [NamedExternref("Event")], shim_idx: 2526, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1156
+ const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9470, __wasm_bindgen_func_elem_9754);
1104
1157
  return addHeapObject(ret);
1105
1158
  },
1106
1159
  __wbindgen_cast_0000000000000003: function(arg0, arg1) {
1107
- // Cast intrinsic for `Closure(Closure { dtor_idx: 2519, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 2472, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1108
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9308, __wasm_bindgen_func_elem_9474);
1160
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 2522, function: Function { arguments: [NamedExternref("MessageEvent")], shim_idx: 2526, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1161
+ const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9470, __wasm_bindgen_func_elem_9754);
1109
1162
  return addHeapObject(ret);
1110
1163
  },
1111
1164
  __wbindgen_cast_0000000000000004: function(arg0, arg1) {
1112
- // Cast intrinsic for `Closure(Closure { dtor_idx: 2519, function: Function { arguments: [], shim_idx: 2521, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1113
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9308, __wasm_bindgen_func_elem_9475);
1165
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 2522, function: Function { arguments: [], shim_idx: 2523, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1166
+ const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_9470, __wasm_bindgen_func_elem_9755);
1114
1167
  return addHeapObject(ret);
1115
1168
  },
1116
1169
  __wbindgen_cast_0000000000000005: function(arg0, arg1) {
1117
- // Cast intrinsic for `Closure(Closure { dtor_idx: 3419, function: Function { arguments: [Externref], shim_idx: 3420, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1118
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_13493, __wasm_bindgen_func_elem_13494);
1170
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 3491, function: Function { arguments: [Externref], shim_idx: 3492, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
1171
+ const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_13736, __wasm_bindgen_func_elem_13737);
1119
1172
  return addHeapObject(ret);
1120
1173
  },
1121
1174
  __wbindgen_cast_0000000000000006: function(arg0) {
@@ -1172,16 +1225,16 @@ function __wbg_get_imports() {
1172
1225
  };
1173
1226
  }
1174
1227
 
1175
- function __wasm_bindgen_func_elem_9475(arg0, arg1) {
1176
- wasm.__wasm_bindgen_func_elem_9475(arg0, arg1);
1228
+ function __wasm_bindgen_func_elem_9755(arg0, arg1) {
1229
+ wasm.__wasm_bindgen_func_elem_9755(arg0, arg1);
1177
1230
  }
1178
1231
 
1179
- function __wasm_bindgen_func_elem_9474(arg0, arg1, arg2) {
1180
- wasm.__wasm_bindgen_func_elem_9474(arg0, arg1, addHeapObject(arg2));
1232
+ function __wasm_bindgen_func_elem_9754(arg0, arg1, arg2) {
1233
+ wasm.__wasm_bindgen_func_elem_9754(arg0, arg1, addHeapObject(arg2));
1181
1234
  }
1182
1235
 
1183
- function __wasm_bindgen_func_elem_13494(arg0, arg1, arg2) {
1184
- wasm.__wasm_bindgen_func_elem_13494(arg0, arg1, addHeapObject(arg2));
1236
+ function __wasm_bindgen_func_elem_13737(arg0, arg1, arg2) {
1237
+ wasm.__wasm_bindgen_func_elem_13737(arg0, arg1, addHeapObject(arg2));
1185
1238
  }
1186
1239
 
1187
1240
 
Binary file
@@ -8,8 +8,12 @@ export const inkwebmessagestream_close: (a: number) => void;
8
8
  export const inkwebmessagestream_write: (a: number, b: number, c: number, d: number) => void;
9
9
  export const inkwebview_bindCanvas: (a: number, b: number, c: number) => void;
10
10
  export const inkwebview_blur: (a: number) => void;
11
+ export const inkwebview_clearSurface: (a: number) => void;
11
12
  export const inkwebview_consumeCloseRequested: (a: number) => number;
13
+ export const inkwebview_consumeContentSizeChanged: (a: number) => number;
12
14
  export const inkwebview_createMessageStream: (a: number, b: number, c: number, d: number, e: number) => number;
15
+ export const inkwebview_currentContentHeight: (a: number) => number;
16
+ export const inkwebview_currentContentWidth: (a: number) => number;
13
17
  export const inkwebview_destroy: (a: number) => void;
14
18
  export const inkwebview_dispatchInput: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
15
19
  export const inkwebview_dispatchMessageEvent: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
@@ -17,19 +21,21 @@ export const inkwebview_dispatchPointer: (a: number, b: number, c: number, d: nu
17
21
  export const inkwebview_focus: (a: number) => void;
18
22
  export const inkwebview_isInteractive: (a: number) => number;
19
23
  export const inkwebview_isRunning: (a: number) => number;
20
- export const inkwebview_new: (a: number, b: number, c: number) => number;
24
+ export const inkwebview_new: (a: number, b: number, c: number, d: number, e: number) => number;
21
25
  export const inkwebview_notifyUserInteraction: (a: number) => void;
22
26
  export const inkwebview_open: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
23
27
  export const inkwebview_openBundle: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
24
28
  export const inkwebview_render: (a: number, b: number) => void;
25
29
  export const inkwebview_resize: (a: number, b: number, c: number, d: number) => void;
26
30
  export const inkwebview_setInteractive: (a: number, b: number) => void;
31
+ export const inkwebview_setLanguageModelConfig: (a: number, b: number, c: number, d: number) => void;
32
+ export const inkwebview_setLayoutMode: (a: number, b: number, c: number) => void;
27
33
  export const main: () => void;
28
- export const __wasm_bindgen_func_elem_9308: (a: number, b: number) => void;
29
- export const __wasm_bindgen_func_elem_13493: (a: number, b: number) => void;
30
- export const __wasm_bindgen_func_elem_9474: (a: number, b: number, c: number) => void;
31
- export const __wasm_bindgen_func_elem_13494: (a: number, b: number, c: number) => void;
32
- export const __wasm_bindgen_func_elem_9475: (a: number, b: number) => void;
34
+ export const __wasm_bindgen_func_elem_9470: (a: number, b: number) => void;
35
+ export const __wasm_bindgen_func_elem_13736: (a: number, b: number) => void;
36
+ export const __wasm_bindgen_func_elem_9754: (a: number, b: number, c: number) => void;
37
+ export const __wasm_bindgen_func_elem_13737: (a: number, b: number, c: number) => void;
38
+ export const __wasm_bindgen_func_elem_9755: (a: number, b: number) => void;
33
39
  export const __wbindgen_export: (a: number, b: number) => number;
34
40
  export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
35
41
  export const __wbindgen_export3: (a: number) => void;