@await-widget/runtime 0.0.30 → 0.0.32

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.
@@ -6,6 +6,7 @@ import http from 'node:http';
6
6
  import os from 'node:os';
7
7
  import path from 'node:path';
8
8
  import process from 'node:process';
9
+ import readline from 'node:readline';
9
10
 
10
11
  const defaultPort = 4343;
11
12
  const maxBodyBytes = 100 * 1024 * 1024;
@@ -16,6 +17,7 @@ const crcTable = makeCrcTable();
16
17
  const bridgeInfoDirectory = '.await';
17
18
  const bridgeInfoFileName = 'bridge.json';
18
19
  const singleWidgetPath = '.';
20
+ const widgetDirectoryError = 'Run await-widget from a package root or first-level widget folder whose package.json includes @await-widget/runtime.';
19
21
 
20
22
  function main() {
21
23
  const options = parseArgs(process.argv.slice(2));
@@ -128,10 +130,10 @@ function parseAppArgs(args) {
128
130
  };
129
131
  }
130
132
 
131
- function startWorkspaceServer(options) {
133
+ async function startWorkspaceServer(options) {
132
134
  let roots;
133
135
  try {
134
- roots = resolveWidgetServerRoots(process.cwd());
136
+ roots = await resolveWidgetServerRoots(process.cwd());
135
137
  } catch (error) {
136
138
  console.error(error.message);
137
139
  process.exit(1);
@@ -394,22 +396,81 @@ function findPackageRoot(start) {
394
396
  }
395
397
  }
396
398
 
397
- function resolveWidgetServerRoots(start) {
399
+ async function resolveWidgetServerRoots(start) {
398
400
  const widgetRoot = path.resolve(start);
399
401
  const packageRoot = findPackageRoot(widgetRoot);
400
402
  if (
401
403
  !packageRoot
402
- || packageRoot === widgetRoot
403
- || path.dirname(widgetRoot) !== packageRoot
404
- || !isValidTopLevelName(path.basename(widgetRoot))
405
404
  || !hasRuntimeDependency(packageRoot)
406
405
  ) {
407
- throw new Error('Run await-widget from a first-level widget folder inside a package whose package.json includes @await-widget/runtime.');
406
+ throw new Error(widgetDirectoryError);
407
+ }
408
+
409
+ if (packageRoot === widgetRoot) {
410
+ return {packageRoot, widgetRoot: await selectWidgetRoot(packageRoot)};
411
+ }
412
+
413
+ if (path.dirname(widgetRoot) !== packageRoot || !isValidTopLevelName(path.basename(widgetRoot))) {
414
+ throw new Error(widgetDirectoryError);
408
415
  }
409
416
 
410
417
  return {packageRoot, widgetRoot};
411
418
  }
412
419
 
420
+ function selectWidgetRoot(packageRoot) {
421
+ const options = [
422
+ {name: `${path.basename(packageRoot)} (root)`, path: packageRoot},
423
+ ...fs.readdirSync(packageRoot, {withFileTypes: true})
424
+ .filter(entry => entry.isDirectory() && isValidTopLevelName(entry.name))
425
+ .sort((left, right) => left.name.localeCompare(right.name))
426
+ .map(entry => ({name: entry.name, path: path.join(packageRoot, entry.name)})),
427
+ ];
428
+ let selected = 0;
429
+ let rendered = false;
430
+ readline.emitKeypressEvents(process.stdin);
431
+ process.stdin.setRawMode(true);
432
+ process.stdin.resume();
433
+ console.log('Select a directory to connect:');
434
+
435
+ const render = () => {
436
+ if (rendered) {
437
+ readline.moveCursor(process.stdout, 0, -options.length);
438
+ readline.clearScreenDown(process.stdout);
439
+ }
440
+
441
+ process.stdout.write(`${options.map((option, index) => `${index === selected ? '❯' : ' '} ${option.name}`).join('\n')}\n`);
442
+ rendered = true;
443
+ };
444
+ render();
445
+
446
+ return new Promise(resolve => {
447
+ const cleanup = () => {
448
+ process.stdin.off('keypress', onKeypress);
449
+ process.stdin.setRawMode(false);
450
+ process.stdin.pause();
451
+ };
452
+ const onKeypress = (_character, key) => {
453
+ if (key.name === 'up' || key.name === 'down') {
454
+ selected = (selected + (key.name === 'up' ? options.length - 1 : 1)) % options.length;
455
+ render();
456
+ return;
457
+ }
458
+
459
+ if (key.name === 'return' || key.name === 'enter') {
460
+ cleanup();
461
+ resolve(options[selected].path);
462
+ return;
463
+ }
464
+
465
+ if (key.ctrl && key.name === 'c') {
466
+ cleanup();
467
+ process.exit(130);
468
+ }
469
+ };
470
+ process.stdin.on('keypress', onKeypress);
471
+ });
472
+ }
473
+
413
474
  function hasRuntimeDependency(packageRoot) {
414
475
  const manifest = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
415
476
  return Boolean(manifest.dependencies?.['@await-widget/runtime'] ?? manifest.devDependencies?.['@await-widget/runtime']);
@@ -948,11 +1009,12 @@ function printHelp() {
948
1009
  await-widget [--port ${defaultPort}]
949
1010
  await-widget app <command> [options]
950
1011
 
951
- Start the Await computer connection from a first-level widget folder under a
952
- package whose package.json includes @await-widget/runtime.
1012
+ Start the Await computer connection from a package root or first-level widget
1013
+ folder whose package.json includes @await-widget/runtime. Starting from the
1014
+ package root opens a directory selector.
953
1015
 
954
1016
  What it does:
955
- - Serves the current widget folder to Await for live sync.
1017
+ - Serves the selected widget folder to Await for live sync.
956
1018
  - Prints a URL to paste into Await's Connect Computer sheet.
957
1019
  - Writes .await/bridge.json in the package root for app commands.
958
1020
  - Sends one-shot JSON app commands with await-widget app <command>.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@await-widget/runtime",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "description": "TypeScript declarations for Await widgets.",
5
5
  "license": "MIT",
6
6
  "author": "Maundy",
package/types/await.d.ts CHANGED
@@ -213,6 +213,20 @@ declare module 'await' {
213
213
  children?: never;
214
214
  },
215
215
  ): NativeView;
216
+ export function XFlip(
217
+ props: AxisFlipValue &
218
+ ID &
219
+ Mods & {
220
+ children?: never;
221
+ },
222
+ ): NativeView;
223
+ export function YFlip(
224
+ props: AxisFlipValue &
225
+ ID &
226
+ Mods & {
227
+ children?: never;
228
+ },
229
+ ): NativeView;
216
230
  export function HFlip(
217
231
  props: FlipValue &
218
232
  ID &
package/types/bridge.d.ts CHANGED
@@ -132,6 +132,7 @@ type AwaitDefineConfig<T extends Record<string, unknown>, Intents> = {
132
132
  context: TimelineContext,
133
133
  ) => Timeline<T> | Promise<Timeline<T>>;
134
134
  widgetFamilies?: WidgetFamily[];
135
+ autoAccented?: boolean;
135
136
  widgetIntents?: {
136
137
  [IntentKey in keyof Intents]: Intents[IntentKey] extends (
137
138
  ...args: infer IntentArguments
@@ -165,6 +166,7 @@ export declare const AwaitEnv: {
165
166
  readonly tag: number;
166
167
  readonly host: 'app' | 'widget';
167
168
  readonly version: string;
169
+ readonly appVersion: string;
168
170
  test(...args: unknown[]): unknown;
169
171
  };
170
172
  type AwaitGlobal = typeof Await;
package/types/model.d.ts CHANGED
@@ -4,6 +4,12 @@ type ColorScheme = 'light' | 'dark';
4
4
 
5
5
  type RenderingMode = 'fullColor' | 'accented' | 'vibrant';
6
6
 
7
+ type Accented =
8
+ | 'fullColor'
9
+ | 'accented'
10
+ | 'accentedDesaturated'
11
+ | 'desaturated';
12
+
7
13
  type Update = Date | 'end' | 'rapid' | 'never';
8
14
 
9
15
  type WidgetFamily =
@@ -71,6 +77,7 @@ type AwaitWeatherConfig = {
71
77
  longitude?: number;
72
78
  hourlyLimit?: number;
73
79
  dailyLimit?: number;
80
+ start?: Date;
74
81
  };
75
82
 
76
83
  type AwaitWeatherCurrent = {
package/types/prop.d.ts CHANGED
@@ -114,8 +114,10 @@ type ImageValue = {
114
114
  resizable?: Resizable;
115
115
  /** The level of quality for rendering an image that requires interpolation, such as a scaled image. */
116
116
  interpolation?: Interpolation;
117
- /** A type that indicates how images are rendered */
117
+ /** The mode that indicates how images are rendered */
118
118
  style?: TemplateRenderingMode;
119
+ /** The mode that indicates how images are rendered on widget accented mode */
120
+ accented?: Accented;
119
121
  };
120
122
 
121
123
  type IconValue = {
@@ -160,12 +162,15 @@ type ClockSecondValue = {
160
162
  size: Size;
161
163
  };
162
164
 
163
- type FlipValue = {
165
+ type AxisFlipValue = {
164
166
  index: number;
165
- delta: number;
166
167
  curr: NativeView;
167
168
  prev: NativeView;
168
169
  perspective?: number;
170
+ };
171
+
172
+ type FlipValue = AxisFlipValue & {
173
+ delta: number;
169
174
  shadowOpacity?: number;
170
175
  leadingHidden?: boolean;
171
176
  trailingHidden?: boolean;