@nativescript/cloudflare-desktop 0.0.0-stage → 0.1.0-alpha.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/dist/input.js ADDED
@@ -0,0 +1,162 @@
1
+ import { Modifier } from '@nativescript/cloudflare-protocol';
2
+ /** A press with no release after this long is released where the pointer last was. */
3
+ const GESTURE_TIMEOUT_MS = 5000;
4
+ /** Drag points kept per gesture; enough to replay a drag's path, not every pixel of it. */
5
+ const MAX_DRAG_EVENTS = 120;
6
+ /**
7
+ * Turns viewer input into AppKit events for one window. Events go through
8
+ * the app's own queue (`postEvent`), the only path that drives controls'
9
+ * tracking loops; a direct `sendEvent` or `mouseDown` never presses an
10
+ * NSButton. Nothing reaches other apps, the real cursor never moves, and no
11
+ * Accessibility permission is involved.
12
+ *
13
+ * A press is held back until its release arrives, then the whole gesture is
14
+ * posted at once: a control's tracking loop runs synchronously on this
15
+ * thread from the press until the release, so a release still waiting in a
16
+ * socket message would never be read. Drags therefore show up when the
17
+ * pointer is released, and press-and-hold isn't possible.
18
+ */
19
+ export class InputInjector {
20
+ pressed = new Set();
21
+ eventNumber = 0;
22
+ lastDown = { at: 0, x: 0, y: 0, count: 0 };
23
+ gesture = null;
24
+ gestureTimer;
25
+ lastPointer;
26
+ inject(input, window) {
27
+ if (!window)
28
+ return;
29
+ // Controls ignore clicks in a window that isn't key, and the host usually
30
+ // runs behind the developer's other apps. Making the window key doesn't
31
+ // activate the app, so the developer's own focus stays where it is.
32
+ if (input.type !== 'wheel' && input.kind === 'down' && NSApp.keyWindow !== window)
33
+ window.makeKeyWindow();
34
+ switch (input.type) {
35
+ case 'pointer':
36
+ return this.pointer(input, window);
37
+ case 'wheel':
38
+ return this.wheel(input, window);
39
+ case 'key':
40
+ return this.key(input, window);
41
+ }
42
+ }
43
+ pointer(input, window) {
44
+ const point = windowPoint(window, input.x, input.y);
45
+ const flags = modifierFlags(input.modifiers);
46
+ if (input.kind === 'down')
47
+ this.pressed.add(input.button);
48
+ if (input.kind === 'up')
49
+ this.pressed.delete(input.button);
50
+ let type;
51
+ let clickCount = 1;
52
+ if (input.kind === 'move') {
53
+ type = this.pressed.has(0) ? NSEventType.LeftMouseDragged : this.pressed.has(2) ? NSEventType.RightMouseDragged : NSEventType.MouseMoved;
54
+ clickCount = 0;
55
+ }
56
+ else {
57
+ const down = input.kind === 'down';
58
+ type = input.button === 2 ? (down ? NSEventType.RightMouseDown : NSEventType.RightMouseUp) : down ? NSEventType.LeftMouseDown : NSEventType.LeftMouseUp;
59
+ clickCount = this.clickCount(down, point);
60
+ }
61
+ const event = NSEvent.mouseEventWithTypeLocationModifierFlagsTimestampWindowNumberContextEventNumberClickCountPressure(type, point, flags, uptime(), window.windowNumber, null, this.eventNumber++, clickCount, input.kind === 'down' ? 1 : 0);
62
+ this.lastPointer = { input, window };
63
+ if (input.kind === 'down' && !this.gesture) {
64
+ this.gesture = [event];
65
+ this.gestureTimer = setTimeout(() => this.release(), GESTURE_TIMEOUT_MS);
66
+ }
67
+ else if (this.gesture) {
68
+ if (input.kind === 'move' && this.gesture.length >= MAX_DRAG_EVENTS)
69
+ this.gesture.splice(1, 1);
70
+ this.gesture.push(event);
71
+ if (input.kind === 'up' && this.pressed.size === 0)
72
+ this.flush();
73
+ }
74
+ else {
75
+ NSApp.postEventAtStart(event, false);
76
+ }
77
+ }
78
+ flush() {
79
+ clearTimeout(this.gestureTimer);
80
+ const events = this.gesture ?? [];
81
+ this.gesture = null;
82
+ for (const e of events)
83
+ NSApp.postEventAtStart(e, false);
84
+ }
85
+ /** Ends a gesture whose release never came (the viewer left mid-drag). */
86
+ release() {
87
+ const last = this.lastPointer;
88
+ if (!this.gesture || !last)
89
+ return this.flush();
90
+ for (const button of [...this.pressed])
91
+ this.pointer({ ...last.input, kind: 'up', button }, last.window);
92
+ this.flush();
93
+ }
94
+ /** Double and triple clicks: AppKit reads the count from each event rather than inferring it. */
95
+ clickCount(down, point) {
96
+ if (!down)
97
+ return this.lastDown.count;
98
+ const now = Date.now();
99
+ const near = Math.abs(point.x - this.lastDown.x) < 4 && Math.abs(point.y - this.lastDown.y) < 4;
100
+ const count = near && now - this.lastDown.at < 400 ? this.lastDown.count + 1 : 1;
101
+ this.lastDown = { at: now, x: point.x, y: point.y, count };
102
+ return count;
103
+ }
104
+ wheel(input, window) {
105
+ const point = windowPoint(window, input.x, input.y);
106
+ // NSEvent has no public scroll-wheel constructor; build a CGEvent and wrap it.
107
+ const cg = CGEventCreateScrollWheelEvent2(null, 0 /* pixels */, 2, Math.round(-input.dy), Math.round(-input.dx), 0);
108
+ if (!cg)
109
+ return;
110
+ const screen = window.convertPointToScreen(point);
111
+ const mainHeight = NSScreen.screens.objectAtIndex(0).frame.size.height;
112
+ CGEventSetLocation(cg, { x: screen.x, y: mainHeight - screen.y });
113
+ CGEventSetIntegerValueField(cg, 91 /* kCGMouseEventWindowUnderMousePointer */, window.windowNumber);
114
+ CGEventSetIntegerValueField(cg, 92 /* kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent */, window.windowNumber);
115
+ const event = NSEvent.eventWithCGEvent(cg);
116
+ if (event)
117
+ NSApp.postEventAtStart(event, false);
118
+ }
119
+ key(input, window) {
120
+ const mapped = KEYS[input.code];
121
+ if (!mapped)
122
+ return;
123
+ const [keyCode, base] = mapped;
124
+ const printable = input.key.length === 1;
125
+ const characters = printable ? input.key : (SPECIAL_CHARS[input.code] ?? base);
126
+ const event = NSEvent.keyEventWithTypeLocationModifierFlagsTimestampWindowNumberContextCharactersCharactersIgnoringModifiersIsARepeatKeyCode(input.kind === 'down' ? NSEventType.KeyDown : NSEventType.KeyUp, { x: 0, y: 0 }, modifierFlags(input.modifiers), uptime(), window.windowNumber, null, characters, SPECIAL_CHARS[input.code] ?? base, input.repeat, keyCode);
127
+ NSApp.postEventAtStart(event, false);
128
+ }
129
+ }
130
+ /** A frame fraction (0..1 from the top-left, title bar included) as a point in the window's base coordinates. */
131
+ function windowPoint(window, x, y) {
132
+ const { width, height } = window.frame.size;
133
+ return { x: clamp(x) * width, y: (1 - clamp(y)) * height };
134
+ }
135
+ const clamp = (v) => (Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : 0);
136
+ const uptime = () => NSProcessInfo.processInfo.systemUptime;
137
+ function modifierFlags(m) {
138
+ return (m & Modifier.shift ? 1 << 17 : 0) | (m & Modifier.ctrl ? 1 << 18 : 0) | (m & Modifier.alt ? 1 << 19 : 0) | (m & Modifier.meta ? 1 << 20 : 0);
139
+ }
140
+ /** DOM `KeyboardEvent.code` → [macOS virtual key code, character without modifiers] (ANSI layout). */
141
+ const KEYS = {
142
+ KeyA: [0, 'a'], KeyS: [1, 's'], KeyD: [2, 'd'], KeyF: [3, 'f'], KeyH: [4, 'h'], KeyG: [5, 'g'], KeyZ: [6, 'z'], KeyX: [7, 'x'],
143
+ KeyC: [8, 'c'], KeyV: [9, 'v'], KeyB: [11, 'b'], KeyQ: [12, 'q'], KeyW: [13, 'w'], KeyE: [14, 'e'], KeyR: [15, 'r'], KeyY: [16, 'y'],
144
+ KeyT: [17, 't'], Digit1: [18, '1'], Digit2: [19, '2'], Digit3: [20, '3'], Digit4: [21, '4'], Digit6: [22, '6'], Digit5: [23, '5'],
145
+ Equal: [24, '='], Digit9: [25, '9'], Digit7: [26, '7'], Minus: [27, '-'], Digit8: [28, '8'], Digit0: [29, '0'], BracketRight: [30, ']'],
146
+ KeyO: [31, 'o'], KeyU: [32, 'u'], BracketLeft: [33, '['], KeyI: [34, 'i'], KeyP: [35, 'p'], Enter: [36, '\r'], KeyL: [37, 'l'],
147
+ KeyJ: [38, 'j'], Quote: [39, "'"], KeyK: [40, 'k'], Semicolon: [41, ';'], Backslash: [42, '\\'], Comma: [43, ','], Slash: [44, '/'],
148
+ KeyN: [45, 'n'], KeyM: [46, 'm'], Period: [47, '.'], Tab: [48, '\t'], Space: [49, ' '], Backquote: [50, '`'], Backspace: [51, '\x7f'],
149
+ Escape: [53, '\x1b'], NumpadEnter: [76, '\x03'],
150
+ F1: [122, ''], F2: [120, ''], F3: [99, ''], F4: [118, ''], F5: [96, ''], F6: [97, ''], F7: [98, ''], F8: [100, ''], F9: [101, ''],
151
+ F10: [109, ''], F11: [103, ''], F12: [111, ''],
152
+ Home: [115, ''], PageUp: [116, ''], Delete: [117, ''], End: [119, ''], PageDown: [121, ''],
153
+ ArrowLeft: [123, ''], ArrowRight: [124, ''], ArrowDown: [125, ''], ArrowUp: [126, ''],
154
+ };
155
+ /** AppKit's private-use function-key characters (NSUpArrowFunctionKey and friends). */
156
+ const SPECIAL_CHARS = {
157
+ Enter: '\r', Tab: '\t', Backspace: '\x7f', Escape: '\x1b',
158
+ ArrowUp: '', ArrowDown: '', ArrowLeft: '', ArrowRight: '',
159
+ F1: '', F2: '', F3: '', F4: '', F5: '', F6: '', F7: '', F8: '', F9: '',
160
+ F10: '', F11: '', F12: '',
161
+ Delete: '', Home: '', End: '', PageUp: '', PageDown: '',
162
+ };
@@ -0,0 +1,3 @@
1
+ export declare function installLoader(): void;
2
+ /** Fetches every module reachable from `entry` that isn't cached yet; resolves to how many were fetched. */
3
+ export declare function prefetch(entry: string): Promise<number>;
package/dist/loader.js ADDED
@@ -0,0 +1,66 @@
1
+ import { registerHooks } from 'node:module';
2
+ import { init, parse } from 'es-module-lexer';
3
+ /**
4
+ * Remote ES modules for Node. Node's sync loader hooks can't fetch, so an
5
+ * async walk of the module graph fills this cache first and the hooks serve
6
+ * from it. Edge module URLs are versioned and immutable: a cached URL never
7
+ * needs fetching again.
8
+ */
9
+ const sources = new Map();
10
+ let installed = false;
11
+ const isRemote = (u) => u.startsWith('http://') || u.startsWith('https://');
12
+ const isRelative = (s) => s.startsWith('/') || s.startsWith('./') || s.startsWith('../');
13
+ export function installLoader() {
14
+ if (installed)
15
+ return;
16
+ installed = true;
17
+ registerHooks({
18
+ resolve(specifier, context, next) {
19
+ if (isRemote(specifier))
20
+ return { url: specifier, format: 'module', shortCircuit: true };
21
+ if (context.parentURL && isRemote(context.parentURL) && isRelative(specifier)) {
22
+ return { url: new URL(specifier, context.parentURL).href, format: 'module', shortCircuit: true };
23
+ }
24
+ return next(specifier, context);
25
+ },
26
+ load(url, context, next) {
27
+ if (!isRemote(url))
28
+ return next(url, context);
29
+ const source = sources.get(url);
30
+ if (source === undefined)
31
+ throw new Error(`${url} was imported before it was fetched`);
32
+ return { format: 'module', source, shortCircuit: true };
33
+ },
34
+ });
35
+ }
36
+ /** Fetches every module reachable from `entry` that isn't cached yet; resolves to how many were fetched. */
37
+ export async function prefetch(entry) {
38
+ await init;
39
+ const pending = new Map();
40
+ let fetched = 0;
41
+ const visit = (url) => {
42
+ if (sources.has(url))
43
+ return Promise.resolve();
44
+ let p = pending.get(url);
45
+ if (p)
46
+ return p;
47
+ p = (async () => {
48
+ const res = await fetch(url);
49
+ const source = await res.text();
50
+ // The edge answers a stale or broken module with a module that throws, so its message reaches the console.
51
+ if (!res.ok && !source.startsWith('throw '))
52
+ throw new Error(`${url}: HTTP ${res.status}`);
53
+ sources.set(url, source);
54
+ fetched++;
55
+ const [imports] = parse(source);
56
+ await Promise.all(imports
57
+ .map((i) => i.specifier)
58
+ .filter((s) => !!s && (isRemote(s) || isRelative(s)))
59
+ .map((s) => visit(new URL(s, url).href)));
60
+ })();
61
+ pending.set(url, p);
62
+ return p;
63
+ };
64
+ await visit(entry);
65
+ return fetched;
66
+ }
package/dist/rpc.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { RpcCall } from '@nativescript/cloudflare-protocol';
2
+ export declare function handleRpc(call: RpcCall, allowEval: boolean): Promise<unknown>;
package/dist/rpc.js ADDED
@@ -0,0 +1,85 @@
1
+ import { toJsonSafe } from './serialize.js';
2
+ import { ownWindow, projectWindow } from './stream.js';
3
+ const AsyncFunction = Object.getPrototypeOf(async () => { }).constructor;
4
+ export async function handleRpc(call, allowEval) {
5
+ const window = projectWindow();
6
+ switch (call.method) {
7
+ case 'eval': {
8
+ if (!allowEval)
9
+ throw new Error('eval is off on this Mac. The developer can restart the host with --allow-eval to allow it.');
10
+ const fn = new AsyncFunction('window', call.code);
11
+ return toJsonSafe(await fn(window));
12
+ }
13
+ case 'screenshot':
14
+ if (!window)
15
+ throw new Error('The project has no visible window');
16
+ return (await capturedScreenshot(window, call.maxWidth).catch(() => null)) ?? screenshot(window);
17
+ case 'viewTree':
18
+ if (!window)
19
+ throw new Error('The project has no visible window');
20
+ return viewTree(window.contentView.superview ?? window.contentView, call.depth);
21
+ }
22
+ }
23
+ /**
24
+ * The window as composited, through ScreenCaptureKit: Chromium's page,
25
+ * Liquid Glass and Metal content included.
26
+ */
27
+ async function capturedScreenshot(window, maxWidth) {
28
+ const target = await ownWindow(window.windowNumber);
29
+ if (!target)
30
+ return null;
31
+ const filter = SCContentFilter.alloc().initWithDesktopIndependentWindow(target);
32
+ const config = SCStreamConfiguration.new();
33
+ const { width, height } = window.frame.size;
34
+ const scale = Math.min(window.backingScaleFactor || 1, maxWidth / Math.max(width, 1));
35
+ config.width = Math.max(2, Math.round(width * scale));
36
+ config.height = Math.max(2, Math.round(height * scale));
37
+ config.showsCursor = false;
38
+ config.ignoreShadowsSingleWindow = true;
39
+ const image = await new Promise((resolve, reject) => SCScreenshotManager.captureImageWithFilterConfigurationCompletionHandler(filter, config, (cg, error) => error ? reject(new Error(error.localizedDescription)) : resolve(cg)));
40
+ const rep = NSBitmapImageRep.alloc().initWithCGImage(image);
41
+ const png = rep.representationUsingTypeProperties(NSBitmapImageFileType.PNG, NSDictionary.dictionary());
42
+ return { png: png.base64EncodedStringWithOptions(0), width: rep.pixelsWide, height: rep.pixelsHigh };
43
+ }
44
+ /**
45
+ * Draws the window's view hierarchy into a bitmap, title bar included. Needs
46
+ * no Screen Recording permission, but layers AppKit doesn't draw itself
47
+ * (Metal, some visual effects) come out blank.
48
+ */
49
+ function screenshot(window) {
50
+ const view = window.contentView.superview ?? window.contentView;
51
+ const rep = view.bitmapImageRepForCachingDisplayInRect(view.bounds);
52
+ view.cacheDisplayInRectToBitmapImageRep(view.bounds, rep);
53
+ const width = rep.pixelsWide;
54
+ const height = rep.pixelsHigh;
55
+ const png = rep.representationUsingTypeProperties(NSBitmapImageFileType.PNG, NSDictionary.dictionary());
56
+ return { png: png.base64EncodedStringWithOptions(0), width, height };
57
+ }
58
+ function viewTree(view, depth) {
59
+ const { width, height } = view.frame.size;
60
+ const node = { type: String(view.className), size: `${Math.round(width)}x${Math.round(height)}`, visible: !view.hidden };
61
+ if (view.identifier)
62
+ node.id = String(view.identifier);
63
+ const text = textOf(view);
64
+ if (text)
65
+ node.text = text.slice(0, 120);
66
+ if (depth > 0) {
67
+ const subviews = view.subviews;
68
+ const children = [];
69
+ for (let i = 0; i < subviews.count; i++)
70
+ children.push(viewTree(subviews.objectAtIndex(i), depth - 1));
71
+ if (children.length)
72
+ node.children = children;
73
+ }
74
+ return node;
75
+ }
76
+ function textOf(view) {
77
+ for (const selector of ['stringValue', 'title']) {
78
+ if (view.respondsToSelector(selector)) {
79
+ const value = view[selector];
80
+ if (typeof value === 'string' && value)
81
+ return value;
82
+ }
83
+ }
84
+ return undefined;
85
+ }
@@ -0,0 +1,9 @@
1
+ export interface RuntimeOptions {
2
+ /** A NativeScript.framework binary to load instead of the npm package's. */
3
+ runtime?: string;
4
+ /** Metadata (.nsmd) generated from this Mac's SDK. The npm package's built-in metadata lacks ScreenCaptureKit's SCStream. */
5
+ metadata?: string;
6
+ }
7
+ /** Loads the NativeScript macOS Node-API runtime into this process; every Objective-C API becomes a global. */
8
+ export declare function loadRuntime(options?: RuntimeOptions): Promise<void>;
9
+ export declare function runtimeVersion(): string;
@@ -0,0 +1,38 @@
1
+ import { createRequire } from 'node:module';
2
+ import fs from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ const FRAMEWORKS = ['AppKit', 'ScreenCaptureKit', 'CoreMedia', 'CoreVideo', 'CoreImage'];
5
+ /** Loads the NativeScript macOS Node-API runtime into this process; every Objective-C API becomes a global. */
6
+ export async function loadRuntime(options = {}) {
7
+ options = { ...options, metadata: options.metadata ?? bundledMetadata() };
8
+ if (options.metadata && !fs.existsSync(options.metadata))
9
+ throw new Error(`No metadata at ${options.metadata}`);
10
+ if (options.runtime) {
11
+ const addon = { exports: {} };
12
+ process.dlopen(addon, options.runtime);
13
+ addon.exports.init(options.metadata);
14
+ }
15
+ else {
16
+ if (options.metadata)
17
+ process.env.METADATA_PATH = options.metadata;
18
+ await import('@nativescript/macos-node-api');
19
+ }
20
+ for (const f of FRAMEWORKS)
21
+ objc.import(f);
22
+ // Objects read out of collections are wrapped by classes the runtime has
23
+ // already bound; touching these globals binds them before any stream lists windows.
24
+ void [SCWindow, SCRunningApplication, SCDisplay];
25
+ }
26
+ /** Metadata shipped in the package (see scripts/metadata.mjs), if this copy has it. */
27
+ function bundledMetadata() {
28
+ const file = fileURLToPath(new URL('../metadata/metadata.macos.arm64.nsmd', import.meta.url));
29
+ return fs.existsSync(file) ? file : undefined;
30
+ }
31
+ export function runtimeVersion() {
32
+ try {
33
+ return createRequire(import.meta.url)('@nativescript/macos-node-api/package.json').version;
34
+ }
35
+ catch {
36
+ return 'custom';
37
+ }
38
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * JSON-safe snapshot of an arbitrary value. Native objects are described by
3
+ * their string form rather than walked, since enumerating one can run getters
4
+ * with side effects.
5
+ */
6
+ export declare function toJsonSafe(value: unknown, depth?: number): unknown;
7
+ export declare function formatArgs(args: unknown[]): string[];
@@ -0,0 +1,42 @@
1
+ const MAX_CHARS = 16_000;
2
+ /**
3
+ * JSON-safe snapshot of an arbitrary value. Native objects are described by
4
+ * their string form rather than walked, since enumerating one can run getters
5
+ * with side effects.
6
+ */
7
+ export function toJsonSafe(value, depth = 4) {
8
+ const seen = new WeakSet();
9
+ const walk = (v, d) => {
10
+ if (v === null || typeof v === 'boolean' || typeof v === 'number' || typeof v === 'string')
11
+ return v;
12
+ if (v === undefined)
13
+ return null;
14
+ if (typeof v === 'bigint')
15
+ return v.toString();
16
+ if (typeof v === 'function')
17
+ return `[Function ${v.name || 'anonymous'}]`;
18
+ if (typeof v !== 'object')
19
+ return String(v);
20
+ if (seen.has(v))
21
+ return '[Circular]';
22
+ seen.add(v);
23
+ if (v instanceof Error)
24
+ return { error: v.message, stack: v.stack };
25
+ if (v instanceof NSObject)
26
+ return String(v);
27
+ if (d <= 0)
28
+ return Array.isArray(v) ? `[Array(${v.length})]` : '[Object]';
29
+ if (Array.isArray(v))
30
+ return v.slice(0, 100).map((x) => walk(x, d - 1));
31
+ const out = {};
32
+ for (const k of Object.keys(v).slice(0, 100))
33
+ out[k] = walk(v[k], d - 1);
34
+ return out;
35
+ };
36
+ const result = walk(value, depth);
37
+ const text = JSON.stringify(result);
38
+ return text && text.length > MAX_CHARS ? text.slice(0, MAX_CHARS) + '…[truncated]' : result;
39
+ }
40
+ export function formatArgs(args) {
41
+ return args.map((a) => (typeof a === 'string' ? a : JSON.stringify(toJsonSafe(a, 3)))).map((s) => (s.length > 2000 ? s.slice(0, 2000) + '…' : s));
42
+ }
@@ -0,0 +1,48 @@
1
+ /** The window a project shows: AppKit's main window, else the frontmost visible one. */
2
+ export declare function projectWindow(): any;
3
+ /**
4
+ * Streams the project's window to the stream relay while anyone watches,
5
+ * and injects the input viewers send back.
6
+ */
7
+ export declare class WindowStreamer {
8
+ private url;
9
+ private onState?;
10
+ private ws?;
11
+ private viewers;
12
+ private capture?;
13
+ private starting;
14
+ private ci?;
15
+ private input;
16
+ private frames;
17
+ private quality;
18
+ private budget;
19
+ private budgetAt;
20
+ private framed;
21
+ private backoff;
22
+ private closed;
23
+ private timer?;
24
+ private stopTimer?;
25
+ constructor(url: string, onState?: ((streaming: boolean, viewers: number) => void) | undefined);
26
+ open(): void;
27
+ close(): void;
28
+ /** Call after each render: a new version may have replaced the window being captured. */
29
+ retarget(): void;
30
+ private sync;
31
+ private start;
32
+ private stop;
33
+ private frame;
34
+ /** Objects created along the way go into `held`, released once the frame is sent. */
35
+ private encode;
36
+ /** Steers JPEG quality so frames stay near the size the budget allows at full frame rate. */
37
+ private adaptQuality;
38
+ private options?;
39
+ private jpegOptions;
40
+ /** Tells viewers the window's size and title when either changed; true if the size did. */
41
+ private sendSize;
42
+ }
43
+ /**
44
+ * This process's own windows as ScreenCaptureKit sees them. Only the
45
+ * current-process listing (macOS 14.4+) includes them: a bare `node` has no
46
+ * bundle and never appears in the general shareable-content list.
47
+ */
48
+ export declare function ownWindow(windowNumber: number): Promise<any>;