@wix/himalaya-cli 0.1575.0 → 0.1577.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.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/index.d.ts +64 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/online-programs/src/index.d.ts +87 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +15 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-online-programs.mjs +42 -0
- package/dist/cli.mjs +10821 -10593
- package/dist/preview-assets.generated.bin +0 -0
- package/fixtures/wix-canned.json +56 -3
- package/guides/himi-json-output.md +8 -0
- package/guides/one-app-section-mappings.md +1 -1
- package/guides/one-app-to-himi-app.md +50 -1
- package/guides/sdk-reference.json +133 -9
- package/package.json +2 -2
- package/templates/beauty-salon/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/beauty-salon-owner/dev/index.ts +52 -27
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/branded-lite/config.ts +7 -0
- package/templates/branded-lite/dev/index.ts +833 -0
- package/templates/branded-lite/himalaya.content.json +3 -0
- package/templates/branded-lite/l10n/en.json +4 -2
- package/templates/branded-lite/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-member-programs/index.ts +658 -0
- package/templates/community-club/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/community-club/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/community-club-owner/dev/index.ts +52 -27
- package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/events-meetups/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/events-meetups-owner/dev/index.ts +52 -27
- package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/gym-fitness/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/gym-fitness-owner/dev/index.ts +52 -27
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/nonprofit-cause/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/nonprofit-cause-owner/dev/index.ts +52 -27
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/owner-lite/dev/index.ts +52 -27
- package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/podcast-creator/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/podcast-creator-owner/dev/index.ts +52 -27
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/portfolio-creative/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/portfolio-creative-owner/dev/index.ts +52 -27
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/restaurant/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/restaurant-owner/dev/index.ts +52 -27
- package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/retail-store/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/retail-store-owner/dev/index.ts +52 -27
- package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
- package/templates/yoga-studio/config.ts +7 -0
- package/templates/yoga-studio/dev/index.ts +833 -0
- package/templates/yoga-studio/himalaya.content.json +3 -0
- package/templates/yoga-studio/tier5-src/_shared/branded-lite-hosted.ts +1 -0
- package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/yoga-studio/tier5-src/himi-branded-lite-member-programs/index.ts +658 -0
- package/templates/yoga-studio-owner/dev/index.ts +52 -27
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +8 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +20 -8
|
@@ -10,7 +10,7 @@ import { getPost, getDraftPost, publishDraftPost, revertDraftPost, deleteDraftPo
|
|
|
10
10
|
import { parseRicosJson } from "@himalaya/wix-rich-content";
|
|
11
11
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
12
12
|
import { richBody } from "../_shared/rich-body.js";
|
|
13
|
-
import { ownerLoadError, isBridgeUnavailable,
|
|
13
|
+
import { ownerLoadError, isBridgeUnavailable, readWasUnreachable, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
|
|
14
14
|
import { DEMO_POSTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
|
|
15
15
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
16
16
|
import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
|
|
@@ -270,14 +270,24 @@ async function refresh(prev: PostState, id: string, actionMessage = "", opts: {
|
|
|
270
270
|
try { post = (await getPost(id)).post; } catch (e) { lastError = postError = e; /* draft-only */ }
|
|
271
271
|
try { draft = (await getDraftPost(id)).draftPost; } catch (e) { lastError = e; /* published-only or missing */ }
|
|
272
272
|
if (!post && !draft) {
|
|
273
|
-
// Both arms swallowed their errors above
|
|
274
|
-
//
|
|
275
|
-
// back to the cached row or the demo post — never "post not found" for a post
|
|
276
|
-
// that was only unreachable.
|
|
273
|
+
// Both arms swallowed their errors above. Neither a failed published read
|
|
274
|
+
// nor a missing draft proves the post is gone.
|
|
277
275
|
// Either read counts: a published-only post's draft read is always a 404, so the
|
|
278
276
|
// published read's failure is the one that says whether the post was only unreachable.
|
|
279
277
|
for (const err of [postError, lastError]) {
|
|
280
|
-
|
|
278
|
+
// getPost may wrap the original read failure when its query fallback is
|
|
279
|
+
// empty. Preserve that cause's status instead of painting the wrapper's
|
|
280
|
+
// "Blog post not found" text for a gateway failure.
|
|
281
|
+
const cause = (err as { cause?: unknown } | undefined)?.cause;
|
|
282
|
+
for (const failure of [cause, err]) {
|
|
283
|
+
if (isBridgeUnavailable(failure) || readWasUnreachable(failure)) throw failure;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
for (const err of [postError, lastError]) {
|
|
287
|
+
// Non-transient access/validation failures keep their status too: the
|
|
288
|
+
// SDK's empty-query wrapper is not the reason this read failed.
|
|
289
|
+
const failure = (err as { cause?: unknown } | undefined)?.cause ?? err;
|
|
290
|
+
if (failure !== undefined && !isNotFound(failure)) throw failure;
|
|
281
291
|
}
|
|
282
292
|
// Wix says it is gone on BOTH reads (a published-only post's draft read is a 404 on its
|
|
283
293
|
// own): its cached row must not outlive it, or an offline load repaints a deleted post.
|
|
@@ -361,7 +371,8 @@ const svc = defineService<PostState, {
|
|
|
361
371
|
} catch (e) {
|
|
362
372
|
// Offline: fall back to the last-synced local row before the demo/error paths.
|
|
363
373
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
364
|
-
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
374
|
+
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
375
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(id) : null;
|
|
365
376
|
if (cached) return cachedDetail(s, cached);
|
|
366
377
|
if (ownerDemoFallback(e)) {
|
|
367
378
|
const demo = demoDetail(s, id);
|
|
@@ -385,7 +396,8 @@ const svc = defineService<PostState, {
|
|
|
385
396
|
return loaded;
|
|
386
397
|
} catch (e) {
|
|
387
398
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
388
|
-
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
399
|
+
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
400
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(s.id) : null;
|
|
389
401
|
if (cached) return cachedDetail(s, cached);
|
|
390
402
|
if (ownerDemoFallback(e)) {
|
|
391
403
|
const demo = demoDetail(s, s.id);
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|
|
@@ -119,6 +119,7 @@ export const HOSTED_SCREEN_VERTICALS: Readonly<Record<string, readonly BrandedLi
|
|
|
119
119
|
himi_portfolio: ["portfolio"],
|
|
120
120
|
himi_portfolio_project: ["portfolio"],
|
|
121
121
|
himi_programs: ["programs"],
|
|
122
|
+
himi_member_programs: ["programs"],
|
|
122
123
|
himi_reservations: ["reservations"],
|
|
123
124
|
himi_reserve: ["restaurants"],
|
|
124
125
|
himi_review: ["reviews"],
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|
|
@@ -65377,16 +65377,17 @@ const SCREENS = runtimeSetting({
|
|
|
65377
65377
|
"type": "VStack",
|
|
65378
65378
|
"props": {
|
|
65379
65379
|
"spacing": 10,
|
|
65380
|
+
"alignment": "leading",
|
|
65380
65381
|
"children": [
|
|
65381
65382
|
{
|
|
65382
|
-
"id": "himi_owner_lite_inbox_thread.
|
|
65383
|
+
"id": "himi_owner_lite_inbox_thread.loading_text",
|
|
65383
65384
|
"body": {
|
|
65384
65385
|
"package": "himalaya",
|
|
65385
|
-
"type": "
|
|
65386
|
+
"type": "Text",
|
|
65386
65387
|
"props": {
|
|
65387
|
-
"
|
|
65388
|
-
"
|
|
65389
|
-
"
|
|
65388
|
+
"text": "Loading conversation…",
|
|
65389
|
+
"style": "body",
|
|
65390
|
+
"color": "textSecondary"
|
|
65390
65391
|
}
|
|
65391
65392
|
}
|
|
65392
65393
|
},
|
|
@@ -65394,51 +65395,75 @@ const SCREENS = runtimeSetting({
|
|
|
65394
65395
|
"id": "",
|
|
65395
65396
|
"body": {
|
|
65396
65397
|
"package": "himalaya",
|
|
65397
|
-
"type": "
|
|
65398
|
+
"type": "VStack",
|
|
65398
65399
|
"props": {
|
|
65400
|
+
"spacing": 10,
|
|
65399
65401
|
"children": [
|
|
65402
|
+
{
|
|
65403
|
+
"id": "himi_owner_lite_inbox_thread.sk1",
|
|
65404
|
+
"body": {
|
|
65405
|
+
"package": "himalaya",
|
|
65406
|
+
"type": "Skeleton",
|
|
65407
|
+
"props": {
|
|
65408
|
+
"width": 220,
|
|
65409
|
+
"height": 44,
|
|
65410
|
+
"cornerRadius": 16
|
|
65411
|
+
}
|
|
65412
|
+
}
|
|
65413
|
+
},
|
|
65400
65414
|
{
|
|
65401
65415
|
"id": "",
|
|
65402
65416
|
"body": {
|
|
65403
65417
|
"package": "himalaya",
|
|
65404
|
-
"type": "
|
|
65405
|
-
"props": {
|
|
65418
|
+
"type": "HStack",
|
|
65419
|
+
"props": {
|
|
65420
|
+
"children": [
|
|
65421
|
+
{
|
|
65422
|
+
"id": "",
|
|
65423
|
+
"body": {
|
|
65424
|
+
"package": "himalaya",
|
|
65425
|
+
"type": "Spacer",
|
|
65426
|
+
"props": {}
|
|
65427
|
+
}
|
|
65428
|
+
},
|
|
65429
|
+
{
|
|
65430
|
+
"id": "himi_owner_lite_inbox_thread.sk2",
|
|
65431
|
+
"body": {
|
|
65432
|
+
"package": "himalaya",
|
|
65433
|
+
"type": "Skeleton",
|
|
65434
|
+
"props": {
|
|
65435
|
+
"width": 180,
|
|
65436
|
+
"height": 44,
|
|
65437
|
+
"cornerRadius": 16
|
|
65438
|
+
}
|
|
65439
|
+
}
|
|
65440
|
+
}
|
|
65441
|
+
]
|
|
65442
|
+
}
|
|
65406
65443
|
}
|
|
65407
65444
|
},
|
|
65408
65445
|
{
|
|
65409
|
-
"id": "himi_owner_lite_inbox_thread.
|
|
65446
|
+
"id": "himi_owner_lite_inbox_thread.sk3",
|
|
65410
65447
|
"body": {
|
|
65411
65448
|
"package": "himalaya",
|
|
65412
65449
|
"type": "Skeleton",
|
|
65413
65450
|
"props": {
|
|
65414
|
-
"width":
|
|
65415
|
-
"height":
|
|
65451
|
+
"width": 240,
|
|
65452
|
+
"height": 64,
|
|
65416
65453
|
"cornerRadius": 16
|
|
65417
65454
|
}
|
|
65418
65455
|
}
|
|
65419
65456
|
}
|
|
65420
65457
|
]
|
|
65421
65458
|
}
|
|
65422
|
-
}
|
|
65423
|
-
|
|
65424
|
-
|
|
65425
|
-
|
|
65426
|
-
"body": {
|
|
65427
|
-
"package": "himalaya",
|
|
65428
|
-
"type": "Skeleton",
|
|
65429
|
-
"props": {
|
|
65430
|
-
"width": 240,
|
|
65431
|
-
"height": 64,
|
|
65432
|
-
"cornerRadius": 16
|
|
65433
|
-
}
|
|
65459
|
+
},
|
|
65460
|
+
"modifiers": {
|
|
65461
|
+
"fillMaxWidth": true,
|
|
65462
|
+
"accessibilityRole": "decorative"
|
|
65434
65463
|
}
|
|
65435
65464
|
}
|
|
65436
65465
|
]
|
|
65437
65466
|
}
|
|
65438
|
-
},
|
|
65439
|
-
"modifiers": {
|
|
65440
|
-
"fillMaxWidth": true,
|
|
65441
|
-
"accessibilityRole": "decorative"
|
|
65442
65467
|
}
|
|
65443
65468
|
}
|
|
65444
65469
|
},
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|
|
@@ -10,7 +10,7 @@ import { getPost, getDraftPost, publishDraftPost, revertDraftPost, deleteDraftPo
|
|
|
10
10
|
import { parseRicosJson } from "@himalaya/wix-rich-content";
|
|
11
11
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
12
12
|
import { richBody } from "../_shared/rich-body.js";
|
|
13
|
-
import { ownerLoadError, isBridgeUnavailable,
|
|
13
|
+
import { ownerLoadError, isBridgeUnavailable, readWasUnreachable, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
|
|
14
14
|
import { DEMO_POSTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
|
|
15
15
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
16
16
|
import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
|
|
@@ -270,14 +270,24 @@ async function refresh(prev: PostState, id: string, actionMessage = "", opts: {
|
|
|
270
270
|
try { post = (await getPost(id)).post; } catch (e) { lastError = postError = e; /* draft-only */ }
|
|
271
271
|
try { draft = (await getDraftPost(id)).draftPost; } catch (e) { lastError = e; /* published-only or missing */ }
|
|
272
272
|
if (!post && !draft) {
|
|
273
|
-
// Both arms swallowed their errors above
|
|
274
|
-
//
|
|
275
|
-
// back to the cached row or the demo post — never "post not found" for a post
|
|
276
|
-
// that was only unreachable.
|
|
273
|
+
// Both arms swallowed their errors above. Neither a failed published read
|
|
274
|
+
// nor a missing draft proves the post is gone.
|
|
277
275
|
// Either read counts: a published-only post's draft read is always a 404, so the
|
|
278
276
|
// published read's failure is the one that says whether the post was only unreachable.
|
|
279
277
|
for (const err of [postError, lastError]) {
|
|
280
|
-
|
|
278
|
+
// getPost may wrap the original read failure when its query fallback is
|
|
279
|
+
// empty. Preserve that cause's status instead of painting the wrapper's
|
|
280
|
+
// "Blog post not found" text for a gateway failure.
|
|
281
|
+
const cause = (err as { cause?: unknown } | undefined)?.cause;
|
|
282
|
+
for (const failure of [cause, err]) {
|
|
283
|
+
if (isBridgeUnavailable(failure) || readWasUnreachable(failure)) throw failure;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
for (const err of [postError, lastError]) {
|
|
287
|
+
// Non-transient access/validation failures keep their status too: the
|
|
288
|
+
// SDK's empty-query wrapper is not the reason this read failed.
|
|
289
|
+
const failure = (err as { cause?: unknown } | undefined)?.cause ?? err;
|
|
290
|
+
if (failure !== undefined && !isNotFound(failure)) throw failure;
|
|
281
291
|
}
|
|
282
292
|
// Wix says it is gone on BOTH reads (a published-only post's draft read is a 404 on its
|
|
283
293
|
// own): its cached row must not outlive it, or an offline load repaints a deleted post.
|
|
@@ -361,7 +371,8 @@ const svc = defineService<PostState, {
|
|
|
361
371
|
} catch (e) {
|
|
362
372
|
// Offline: fall back to the last-synced local row before the demo/error paths.
|
|
363
373
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
364
|
-
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
374
|
+
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
375
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(id) : null;
|
|
365
376
|
if (cached) return cachedDetail(s, cached);
|
|
366
377
|
if (ownerDemoFallback(e)) {
|
|
367
378
|
const demo = demoDetail(s, id);
|
|
@@ -385,7 +396,8 @@ const svc = defineService<PostState, {
|
|
|
385
396
|
return loaded;
|
|
386
397
|
} catch (e) {
|
|
387
398
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
388
|
-
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
399
|
+
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
400
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(s.id) : null;
|
|
389
401
|
if (cached) return cachedDetail(s, cached);
|
|
390
402
|
if (ownerDemoFallback(e)) {
|
|
391
403
|
const demo = demoDetail(s, s.id);
|
|
@@ -65754,16 +65754,17 @@ const SCREENS = runtimeSetting({
|
|
|
65754
65754
|
"type": "VStack",
|
|
65755
65755
|
"props": {
|
|
65756
65756
|
"spacing": 10,
|
|
65757
|
+
"alignment": "leading",
|
|
65757
65758
|
"children": [
|
|
65758
65759
|
{
|
|
65759
|
-
"id": "himi_owner_lite_inbox_thread.
|
|
65760
|
+
"id": "himi_owner_lite_inbox_thread.loading_text",
|
|
65760
65761
|
"body": {
|
|
65761
65762
|
"package": "himalaya",
|
|
65762
|
-
"type": "
|
|
65763
|
+
"type": "Text",
|
|
65763
65764
|
"props": {
|
|
65764
|
-
"
|
|
65765
|
-
"
|
|
65766
|
-
"
|
|
65765
|
+
"text": "Loading conversation…",
|
|
65766
|
+
"style": "body",
|
|
65767
|
+
"color": "textSecondary"
|
|
65767
65768
|
}
|
|
65768
65769
|
}
|
|
65769
65770
|
},
|
|
@@ -65771,51 +65772,75 @@ const SCREENS = runtimeSetting({
|
|
|
65771
65772
|
"id": "",
|
|
65772
65773
|
"body": {
|
|
65773
65774
|
"package": "himalaya",
|
|
65774
|
-
"type": "
|
|
65775
|
+
"type": "VStack",
|
|
65775
65776
|
"props": {
|
|
65777
|
+
"spacing": 10,
|
|
65776
65778
|
"children": [
|
|
65779
|
+
{
|
|
65780
|
+
"id": "himi_owner_lite_inbox_thread.sk1",
|
|
65781
|
+
"body": {
|
|
65782
|
+
"package": "himalaya",
|
|
65783
|
+
"type": "Skeleton",
|
|
65784
|
+
"props": {
|
|
65785
|
+
"width": 220,
|
|
65786
|
+
"height": 44,
|
|
65787
|
+
"cornerRadius": 16
|
|
65788
|
+
}
|
|
65789
|
+
}
|
|
65790
|
+
},
|
|
65777
65791
|
{
|
|
65778
65792
|
"id": "",
|
|
65779
65793
|
"body": {
|
|
65780
65794
|
"package": "himalaya",
|
|
65781
|
-
"type": "
|
|
65782
|
-
"props": {
|
|
65795
|
+
"type": "HStack",
|
|
65796
|
+
"props": {
|
|
65797
|
+
"children": [
|
|
65798
|
+
{
|
|
65799
|
+
"id": "",
|
|
65800
|
+
"body": {
|
|
65801
|
+
"package": "himalaya",
|
|
65802
|
+
"type": "Spacer",
|
|
65803
|
+
"props": {}
|
|
65804
|
+
}
|
|
65805
|
+
},
|
|
65806
|
+
{
|
|
65807
|
+
"id": "himi_owner_lite_inbox_thread.sk2",
|
|
65808
|
+
"body": {
|
|
65809
|
+
"package": "himalaya",
|
|
65810
|
+
"type": "Skeleton",
|
|
65811
|
+
"props": {
|
|
65812
|
+
"width": 180,
|
|
65813
|
+
"height": 44,
|
|
65814
|
+
"cornerRadius": 16
|
|
65815
|
+
}
|
|
65816
|
+
}
|
|
65817
|
+
}
|
|
65818
|
+
]
|
|
65819
|
+
}
|
|
65783
65820
|
}
|
|
65784
65821
|
},
|
|
65785
65822
|
{
|
|
65786
|
-
"id": "himi_owner_lite_inbox_thread.
|
|
65823
|
+
"id": "himi_owner_lite_inbox_thread.sk3",
|
|
65787
65824
|
"body": {
|
|
65788
65825
|
"package": "himalaya",
|
|
65789
65826
|
"type": "Skeleton",
|
|
65790
65827
|
"props": {
|
|
65791
|
-
"width":
|
|
65792
|
-
"height":
|
|
65828
|
+
"width": 240,
|
|
65829
|
+
"height": 64,
|
|
65793
65830
|
"cornerRadius": 16
|
|
65794
65831
|
}
|
|
65795
65832
|
}
|
|
65796
65833
|
}
|
|
65797
65834
|
]
|
|
65798
65835
|
}
|
|
65799
|
-
}
|
|
65800
|
-
|
|
65801
|
-
|
|
65802
|
-
|
|
65803
|
-
"body": {
|
|
65804
|
-
"package": "himalaya",
|
|
65805
|
-
"type": "Skeleton",
|
|
65806
|
-
"props": {
|
|
65807
|
-
"width": 240,
|
|
65808
|
-
"height": 64,
|
|
65809
|
-
"cornerRadius": 16
|
|
65810
|
-
}
|
|
65836
|
+
},
|
|
65837
|
+
"modifiers": {
|
|
65838
|
+
"fillMaxWidth": true,
|
|
65839
|
+
"accessibilityRole": "decorative"
|
|
65811
65840
|
}
|
|
65812
65841
|
}
|
|
65813
65842
|
]
|
|
65814
65843
|
}
|
|
65815
|
-
},
|
|
65816
|
-
"modifiers": {
|
|
65817
|
-
"fillMaxWidth": true,
|
|
65818
|
-
"accessibilityRole": "decorative"
|
|
65819
65844
|
}
|
|
65820
65845
|
}
|
|
65821
65846
|
},
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|
|
@@ -10,7 +10,7 @@ import { getPost, getDraftPost, publishDraftPost, revertDraftPost, deleteDraftPo
|
|
|
10
10
|
import { parseRicosJson } from "@himalaya/wix-rich-content";
|
|
11
11
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
12
12
|
import { richBody } from "../_shared/rich-body.js";
|
|
13
|
-
import { ownerLoadError, isBridgeUnavailable,
|
|
13
|
+
import { ownerLoadError, isBridgeUnavailable, readWasUnreachable, isOwnerPreviewDemo, ownerDemoFallback, ownerWriteError, isNotFound } from "../_shared/owner-load-error.js";
|
|
14
14
|
import { DEMO_POSTS, DEMO_NOTE, DEMO_SAVE_NOTE } from "../_shared/owner-preview-demo.js";
|
|
15
15
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
16
16
|
import { get as dbGet, upsert as dbUpsert, remove as dbRemove, type DbEntity } from "../_shared/owner-local-db.js";
|
|
@@ -270,14 +270,24 @@ async function refresh(prev: PostState, id: string, actionMessage = "", opts: {
|
|
|
270
270
|
try { post = (await getPost(id)).post; } catch (e) { lastError = postError = e; /* draft-only */ }
|
|
271
271
|
try { draft = (await getDraftPost(id)).draftPost; } catch (e) { lastError = e; /* published-only or missing */ }
|
|
272
272
|
if (!post && !draft) {
|
|
273
|
-
// Both arms swallowed their errors above
|
|
274
|
-
//
|
|
275
|
-
// back to the cached row or the demo post — never "post not found" for a post
|
|
276
|
-
// that was only unreachable.
|
|
273
|
+
// Both arms swallowed their errors above. Neither a failed published read
|
|
274
|
+
// nor a missing draft proves the post is gone.
|
|
277
275
|
// Either read counts: a published-only post's draft read is always a 404, so the
|
|
278
276
|
// published read's failure is the one that says whether the post was only unreachable.
|
|
279
277
|
for (const err of [postError, lastError]) {
|
|
280
|
-
|
|
278
|
+
// getPost may wrap the original read failure when its query fallback is
|
|
279
|
+
// empty. Preserve that cause's status instead of painting the wrapper's
|
|
280
|
+
// "Blog post not found" text for a gateway failure.
|
|
281
|
+
const cause = (err as { cause?: unknown } | undefined)?.cause;
|
|
282
|
+
for (const failure of [cause, err]) {
|
|
283
|
+
if (isBridgeUnavailable(failure) || readWasUnreachable(failure)) throw failure;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
for (const err of [postError, lastError]) {
|
|
287
|
+
// Non-transient access/validation failures keep their status too: the
|
|
288
|
+
// SDK's empty-query wrapper is not the reason this read failed.
|
|
289
|
+
const failure = (err as { cause?: unknown } | undefined)?.cause ?? err;
|
|
290
|
+
if (failure !== undefined && !isNotFound(failure)) throw failure;
|
|
281
291
|
}
|
|
282
292
|
// Wix says it is gone on BOTH reads (a published-only post's draft read is a 404 on its
|
|
283
293
|
// own): its cached row must not outlive it, or an offline load repaints a deleted post.
|
|
@@ -361,7 +371,8 @@ const svc = defineService<PostState, {
|
|
|
361
371
|
} catch (e) {
|
|
362
372
|
// Offline: fall back to the last-synced local row before the demo/error paths.
|
|
363
373
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
364
|
-
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
374
|
+
const cached = isNotFound(e) ? (await cacheDrop(id), null)
|
|
375
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(id) : null;
|
|
365
376
|
if (cached) return cachedDetail(s, cached);
|
|
366
377
|
if (ownerDemoFallback(e)) {
|
|
367
378
|
const demo = demoDetail(s, id);
|
|
@@ -385,7 +396,8 @@ const svc = defineService<PostState, {
|
|
|
385
396
|
return loaded;
|
|
386
397
|
} catch (e) {
|
|
387
398
|
// Wix says it is gone (e.g. a delete whose reply was lost): drop the row, never show it.
|
|
388
|
-
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
399
|
+
const cached = isNotFound(e) ? (await cacheDrop(s.id), null)
|
|
400
|
+
: readWasUnreachable(e) || isBridgeUnavailable(e) ? await cacheGet(s.id) : null;
|
|
389
401
|
if (cached) return cachedDetail(s, cached);
|
|
390
402
|
if (ownerDemoFallback(e)) {
|
|
391
403
|
const demo = demoDetail(s, s.id);
|
|
@@ -119,6 +119,7 @@ export const HOSTED_SCREEN_VERTICALS: Readonly<Record<string, readonly BrandedLi
|
|
|
119
119
|
himi_portfolio: ["portfolio"],
|
|
120
120
|
himi_portfolio_project: ["portfolio"],
|
|
121
121
|
himi_programs: ["programs"],
|
|
122
|
+
himi_member_programs: ["programs"],
|
|
122
123
|
himi_reservations: ["reservations"],
|
|
123
124
|
himi_reserve: ["restaurants"],
|
|
124
125
|
himi_review: ["reviews"],
|
|
@@ -194,6 +194,14 @@ export function isTransportFailure(e: unknown): boolean {
|
|
|
194
194
|
return TRANSPORT.some((re) => re.test(msg));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/** A failed READ says nothing about the record's existence when Wix is
|
|
198
|
+
* unreachable, overloaded or failing. Unlike the legacy bridge predicate this
|
|
199
|
+
* is independent of preview mode; a live preview's gateway failure is one too. */
|
|
200
|
+
export function readWasUnreachable(e: unknown): boolean {
|
|
201
|
+
const msg = String((e as Error)?.message ?? e ?? "");
|
|
202
|
+
return isTransportFailure(e) || /HTTP (?:408|429|5\d{2})\b/.test(msg);
|
|
203
|
+
}
|
|
204
|
+
|
|
197
205
|
/** Transport failures that happen while CONNECTING — no connection, no route, no such host,
|
|
198
206
|
* connection refused — so the request provably never left the device. Every other
|
|
199
207
|
* transport failure (a timeout, a reset, a bad or truncated response, a browser's fetch
|