@wix/himalaya-cli 0.848.0 → 0.850.0

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.
@@ -253,6 +253,34 @@ export declare function surfaceById(id: string): PreviewSurface | undefined;
253
253
  * claim a family allowlist and then be served live bindings.
254
254
  */
255
255
  export type SurfaceRenderMode = "frozen" | "interactive";
256
+ /**
257
+ * The widget family a FROZEN surface publishes under, for DISPLAY — or undefined for
258
+ * an interactive app shell.
259
+ *
260
+ * Both gate kinds that mean "frozen" carry a family: `family` because it IS the
261
+ * allowlist key, `projection` because the car still ships its tree under one
262
+ * (`car_list`). That makes this the right thing to name a surface by in a message, and
263
+ * the WRONG thing to branch on — a car and a widget are authored through different
264
+ * doors. Decisions use `isWidgetFamilySurface` below.
265
+ */
266
+ export declare function surfaceFrozenFamily(surface: PreviewSurface): string | undefined;
267
+ /**
268
+ * Is this surface an OS widget — the `defineWidget` population, as distinct from the
269
+ * car, which is frozen too?
270
+ *
271
+ * Named and shared rather than spelled `gate.kind === "family"` at each call site,
272
+ * because the two places that ask (`surfacesForApp`'s produced verdict, and
273
+ * `himi render --device`'s refusal) must give the same answer or #2499 comes back
274
+ * halfway: a surface one of them classes as a widget and the other does not is either
275
+ * advertised as supported while unrenderable, or refused with advice pointing at a
276
+ * door it was not authored through.
277
+ *
278
+ * The car is excluded deliberately, not incidentally. It is authored with
279
+ * `defineView({ surface: "car" })`, gated by a real `androidauto` key (so it never
280
+ * over-claimed), and its viewport exists for the preview — so `defineWidget` advice and
281
+ * a `/v1/widget/<id>` pointer would both be dead ends for it.
282
+ */
283
+ export declare function isWidgetFamilySurface(surface: PreviewSurface): boolean;
256
284
  export declare function surfaceRenderMode(surface: PreviewSurface): SurfaceRenderMode;
257
285
  /**
258
286
  * Ladder rungs that are not themselves surfaces — the shared fallbacks a view can
@@ -316,15 +344,48 @@ export declare function isTargeted(surface: PreviewSurface, platforms: Platforms
316
344
  export interface SurfaceAvailability {
317
345
  readonly surface: PreviewSurface;
318
346
  readonly targeted: boolean;
319
- /** When not targeted, the exact opt-in to add. Drives the picker's tooltip. */
347
+ /** When not targeted because of the BINARY envelope, the exact platforms.json
348
+ * opt-in to add. Drives the picker's tooltip. Absent for a widget family that
349
+ * is untargeted for lack of a widget — no platforms.json key opts that in. */
320
350
  readonly optIn?: string;
351
+ /**
352
+ * For a WIDGET FAMILY (`isWidgetFamilySurface`) — does this app actually PRODUCE a
353
+ * snapshot for it? Only present when the caller supplied the produced set;
354
+ * `undefined` means "not measured", which is not the same as `false` and must not be
355
+ * rendered as one.
356
+ *
357
+ * Widget families and NOTHING else, the car included — it is frozen too, but it is
358
+ * gated by a real `androidauto` key (so it never over-claimed) and is authored with
359
+ * `defineView({ surface: "car" })`, so a `defineWidget`-shaped verdict would be the
360
+ * wrong answer rather than a missing one. An app shell has nothing to produce at all.
361
+ */
362
+ readonly produced?: boolean;
363
+ /** When a widget family is untargeted because nothing produces it, what to author. */
364
+ readonly needs?: string;
321
365
  }
322
366
  /**
323
367
  * The full catalog with a targeted flag — NOT a filtered list. The picker shows
324
368
  * every surface and dims the untargeted ones, so authors discover what their app
325
369
  * could also be, instead of only seeing what it already is.
370
+ *
371
+ * `producedFamilies` — the widget families this app actually produces a snapshot for
372
+ * (`GET /v1/widgets`, or a scan of its built bundles). Supply it and a frozen surface
373
+ * reports the truth; omit it and the answer is the binary envelope alone, as before.
374
+ *
375
+ * Why it exists (#2499): the four native widget families carry `platformKey: null`
376
+ * (`web_card` and `watch_complication` are the exceptions — they ride `web`/`watchos`),
377
+ * so for those four `isTargeted` short-circuits to `true` and `himi surfaces` reported
378
+ * `widget:ios_home`, `widget:ios_lock`, `widget:android_home` and
379
+ * `widget:ios_live_activity` as targeted for EVERY app — declared widgets or not.
380
+ * A tester read that as support, found
381
+ * `/v1/widgets` empty, and summarized it as "everything advertises the capability
382
+ * except the capability". The envelope answer was not wrong so much as answering a
383
+ * different question: iOS and Android are implicit, so the binary CAN host a widget;
384
+ * whether this app HAS one is a fact about its bundles, and only the produced set
385
+ * carries it. `isTargeted` is deliberately left alone — `resolveSurfaceEnvelope` asks
386
+ * the binary question and must keep getting the binary answer.
326
387
  */
327
- export declare function surfacesForApp(platforms: PlatformsJson): readonly SurfaceAvailability[];
388
+ export declare function surfacesForApp(platforms: PlatformsJson, producedFamilies?: Iterable<string>): readonly SurfaceAvailability[];
328
389
  export interface SurfaceEnvelopeResolution {
329
390
  /** Surfaces this app actually runs, in catalog order. */
330
391
  readonly enabled: readonly string[];
@@ -9232,6 +9232,13 @@ var PREVIEW_SURFACES = [
9232
9232
  function surfaceById(id) {
9233
9233
  return PREVIEW_SURFACES.find((s) => s.id === id);
9234
9234
  }
9235
+ function surfaceFrozenFamily(surface) {
9236
+ const gate = surface.gate;
9237
+ return gate.kind === "family" || gate.kind === "projection" ? gate.family : void 0;
9238
+ }
9239
+ function isWidgetFamilySurface(surface) {
9240
+ return surface.gate.kind === "family";
9241
+ }
9235
9242
  function surfaceRenderMode(surface) {
9236
9243
  const { kind } = surface.gate;
9237
9244
  return kind === "family" || kind === "projection" ? "frozen" : "interactive";
@@ -9295,10 +9302,33 @@ function isTargeted(surface, platforms) {
9295
9302
  if (surface.platformKey === "macos") return platforms.macos !== false;
9296
9303
  return platforms[surface.platformKey] === true;
9297
9304
  }
9298
- function surfacesForApp(platforms) {
9305
+ function surfacesForApp(platforms, producedFamilies) {
9306
+ const produced = producedFamilies === void 0 ? void 0 : producedFamilies instanceof Set ? producedFamilies : new Set(producedFamilies);
9299
9307
  return PREVIEW_SURFACES.map((surface) => {
9300
- const targeted = isTargeted(surface, platforms);
9301
- return targeted ? { surface, targeted } : { surface, targeted, optIn: `"${surface.platformKey}": true` };
9308
+ const inEnvelope = isTargeted(surface, platforms);
9309
+ const family = isWidgetFamilySurface(surface) ? surfaceFrozenFamily(surface) : void 0;
9310
+ if (produced && family !== void 0) {
9311
+ const isProduced = produced.has(family);
9312
+ return inEnvelope && isProduced ? { surface, targeted: true, produced: true } : {
9313
+ surface,
9314
+ targeted: false,
9315
+ produced: isProduced,
9316
+ // The four native families carry no platform key, so there is nothing to
9317
+ // offer; `web_card` and `watch_complication` DO have one, and when that is
9318
+ // the half that is missing it is still the right advice. Hence the guard —
9319
+ // it is load-bearing for two families, not defensive padding.
9320
+ ...inEnvelope ? {} : surface.platformKey ? { optIn: `"${surface.platformKey}": true` } : {},
9321
+ ...isProduced ? {} : {
9322
+ // The rebuild half is not padding: the produced set is read off BUILT
9323
+ // bundles, so an author who has just written the registration and not
9324
+ // rebuilt lands here too, and "write defineWidget" alone would be advice
9325
+ // to write the code they are looking at.
9326
+ needs: `defineWidget({ family: "${family}", \u2026 }) in a Tier-5 bundle \u2014 and a rebuild, if you just added it`
9327
+ }
9328
+ };
9329
+ }
9330
+ if (inEnvelope) return { surface, targeted: true };
9331
+ return surface.platformKey ? { surface, targeted: false, optIn: `"${surface.platformKey}": true` } : { surface, targeted: false };
9302
9332
  });
9303
9333
  }
9304
9334
  function resolveSurfaceEnvelope(platforms, requested) {
@@ -12814,6 +12844,7 @@ export {
12814
12844
  isValidAppId,
12815
12845
  isValidStreamPolicy,
12816
12846
  isViewTarget,
12847
+ isWidgetFamilySurface,
12817
12848
  layoutDirection,
12818
12849
  parseNumeric,
12819
12850
  primarySubtag,
@@ -12834,6 +12865,7 @@ export {
12834
12865
  stripOriginParams,
12835
12866
  summarize,
12836
12867
  surfaceById,
12868
+ surfaceFrozenFamily,
12837
12869
  surfaceRenderMode,
12838
12870
  surfacesForApp,
12839
12871
  validate,