@wix/himalaya-cli 0.1543.0 → 0.1545.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/core/sdk/agent/src/index.d.ts +5 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/state/src/index.d.ts +14 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/state/src/read.d.ts +60 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/auth-providers/wix/src/index.d.ts +3 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/activity-counters-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/ai-site-chat/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/analytics/src/index.d.ts +42 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/async-jobs/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/automations-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/badges-v2/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/billing-tax-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +5 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/bookings-v2/src/extensions.d.ts +4 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/bookings-v2/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/business-feed/src/index.d.ts +11 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/business-tools-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/chat-web/src/index.d.ts +22 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/comments-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/contacts/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/coupons/src/index.d.ts +24 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/crm-tasks/src/index.d.ts +11 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/dashboard-setup/src/index.d.ts +11 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/data-collections-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/donations/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/ecom/src/extensions.d.ts +6 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/ecom/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/email-marketing-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/index.d.ts +24 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/faq-v2/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/forms/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/forum/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/genie-chat/src/index.d.ts +11 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/gift-cards/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/groups/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/inbox/src/extensions.d.ts +2 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/inbox/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/invoices/src/index.d.ts +24 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/index.d.ts +28 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/marketing-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-feed-viewer/src/index.d.ts +23 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-v1/src/index.d.ts +25 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/new-releases/src/index.d.ts +23 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/notification-preferences/src/index.d.ts +23 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/notifications-v3/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/online-programs/src/index.d.ts +25 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/portfolio/src/index.d.ts +25 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/pricing-plans/src/index.d.ts +28 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/redirects-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/restaurants/src/extensions.d.ts +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/restaurants/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/reviews/src/index.d.ts +24 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/seo-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/site-list/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/site-media/src/index.d.ts +11 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/social-feed/src/index.d.ts +23 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-collections/src/display.d.ts +3 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-collections/src/index.d.ts +27 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/catalog.d.ts +7 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/display.d.ts +4 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/extensions.d.ts +2 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/table-reservations/src/index.d.ts +25 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/users/src/index.d.ts +23 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/video/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/wix-data/src/index.d.ts +27 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/workflows-v1/src/index.d.ts +19 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk-auto/_shared/runtime.generated.d.ts +8 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/checkout.mjs +12 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +36 -11
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/state.mjs +206 -12
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-activity-counters.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-ai-site-chat.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-analytics.mjs +21 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-async-jobs.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-automations.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-badges.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-billing-tax.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-blog.mjs +31 -14
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-bookings.mjs +26 -12
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-business-tools.mjs +20 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-chat-web.mjs +29 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-comments.mjs +28 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-contacts.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-coupons.mjs +14 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-data-collections.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-data.mjs +15 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-donations.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-ecom.mjs +33 -16
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-email-marketing.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +14 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-faq.mjs +20 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-forms.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-forum.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-gift-cards.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-groups.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-inbox.mjs +21 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-invoices.mjs +14 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +16 -8
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-marketing.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members-feed-viewer.mjs +21 -10
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members.mjs +17 -8
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-new-releases.mjs +17 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-notification-preferences.mjs +20 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-notifications.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-online-programs.mjs +16 -8
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-portfolio.mjs +16 -8
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-pricing-plans.mjs +22 -14
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-redirects.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-restaurants.mjs +22 -7
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-reviews.mjs +14 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-rich-content-editor.mjs +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-seo.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-site-list.mjs +19 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-social-feed.mjs +15 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores-collections.mjs +20 -10
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +116 -83
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-table-reservations.mjs +16 -8
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-users.mjs +15 -5
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-video.mjs +9 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-workflows.mjs +19 -5
- package/dist/cli.mjs +90 -57
- package/dist/preview-assets.generated.bin +0 -0
- package/fixtures/wix-canned.json +8 -8
- package/guides/dynamic-list.service.ts +38 -29
- package/guides/form-submit.service.ts +2 -1
- package/guides/index.json +6 -0
- package/guides/offline-reading.md +63 -0
- package/guides/one-app-to-himi-app.md +5 -3
- package/guides/recipe-dynamic-list.md +2 -0
- package/guides/recipe-four-state.md +1 -0
- package/guides/sdk-reference.json +225 -99
- package/guides/testing-himi-apps.md +2 -0
- package/guides/tier-5-add-a-screen.md +2 -0
- package/guides/wix-api-usage.md +9 -2
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +4 -3
- package/templates/beauty-salon/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/beauty-salon/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/beauty-salon/tier5-src/himi-branded-lite-orders/index.ts +3 -0
- package/templates/beauty-salon-owner/dev/index.ts +19 -19
- package/templates/beauty-salon-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/branded-lite/dev/index.ts +38 -20
- package/templates/branded-lite/tier5-src/_shared/collection-query-legacy.ts +194 -0
- package/templates/branded-lite/tier5-src/_shared/collection-query.ts +158 -99
- package/templates/branded-lite/tier5-src/_shared/collection-service.ts +31 -11
- package/templates/branded-lite/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/branded-lite/tier5-src/_shared/read-service.ts +255 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-orders/index.ts +3 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-shop/index.ts +202 -159
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +130 -201
- package/templates/community-club/dev/index.ts +4 -4
- package/templates/community-club/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/community-club/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/community-club-owner/dev/index.ts +19 -19
- package/templates/community-club-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/community-club-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/events-meetups/dev/index.ts +3 -3
- package/templates/events-meetups/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/events-meetups/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/events-meetups-owner/dev/index.ts +17 -17
- package/templates/events-meetups-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/events-meetups-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/gym-fitness/dev/index.ts +5 -4
- package/templates/gym-fitness/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/gym-fitness/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/gym-fitness/tier5-src/himi-branded-lite-orders/index.ts +3 -0
- package/templates/gym-fitness-owner/dev/index.ts +20 -20
- package/templates/gym-fitness-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/nonprofit-cause/dev/index.ts +4 -4
- package/templates/nonprofit-cause/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/nonprofit-cause/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/nonprofit-cause-owner/dev/index.ts +18 -18
- package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/owner-lite/dev/index.ts +20 -20
- package/templates/owner-lite/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/owner-lite/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/podcast-creator/dev/index.ts +4 -4
- package/templates/podcast-creator/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/podcast-creator/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/podcast-creator-owner/dev/index.ts +19 -19
- package/templates/podcast-creator-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/portfolio-creative/dev/index.ts +5 -4
- package/templates/portfolio-creative/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/portfolio-creative/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-orders/index.ts +3 -0
- package/templates/portfolio-creative-owner/dev/index.ts +19 -19
- package/templates/portfolio-creative-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/restaurant/dev/index.ts +3 -3
- package/templates/restaurant/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/restaurant/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/restaurant-owner/dev/index.ts +20 -20
- package/templates/restaurant-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/restaurant-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/retail-store/dev/index.ts +19 -1
- package/templates/retail-store/tier5-src/_shared/collection-query-legacy.ts +194 -0
- package/templates/retail-store/tier5-src/_shared/collection-query.ts +158 -99
- package/templates/retail-store/tier5-src/_shared/collection-service.ts +31 -11
- package/templates/retail-store/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/retail-store/tier5-src/_shared/read-service.ts +255 -0
- package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/retail-store/tier5-src/himi-branded-lite-orders/index.ts +3 -0
- package/templates/retail-store/tier5-src/himi-branded-lite-shop/index.ts +202 -159
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +130 -201
- package/templates/retail-store-owner/dev/index.ts +18 -18
- package/templates/retail-store-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/retail-store-owner/tier5-src/_shared/owner-module-data.ts +1 -1
- package/templates/yoga-studio/dev/index.ts +4 -4
- package/templates/yoga-studio/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/yoga-studio/tier5-src/_shared/iap-presentation.ts +7 -3
- package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +1 -1
- package/templates/yoga-studio-owner/dev/index.ts +18 -18
- package/templates/yoga-studio-owner/tier5-src/_shared/collection-service.ts +6 -9
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-module-data.ts +1 -1
|
@@ -584,7 +584,7 @@ const SCREENS = runtimeSetting({
|
|
|
584
584
|
"package": "himalaya",
|
|
585
585
|
"type": "Text",
|
|
586
586
|
"props": {
|
|
587
|
-
"text": "Showing
|
|
587
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
588
588
|
"style": "caption",
|
|
589
589
|
"color": "textSecondary"
|
|
590
590
|
}
|
|
@@ -3938,7 +3938,7 @@ const SCREENS = runtimeSetting({
|
|
|
3938
3938
|
"package": "himalaya",
|
|
3939
3939
|
"type": "Text",
|
|
3940
3940
|
"props": {
|
|
3941
|
-
"text": "Showing
|
|
3941
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
3942
3942
|
"style": "caption",
|
|
3943
3943
|
"color": "textSecondary"
|
|
3944
3944
|
}
|
|
@@ -7205,7 +7205,7 @@ const SCREENS = runtimeSetting({
|
|
|
7205
7205
|
"package": "himalaya",
|
|
7206
7206
|
"type": "Text",
|
|
7207
7207
|
"props": {
|
|
7208
|
-
"text": "Showing
|
|
7208
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
7209
7209
|
"style": "caption",
|
|
7210
7210
|
"color": "textSecondary"
|
|
7211
7211
|
}
|
|
@@ -10379,7 +10379,7 @@ const SCREENS = runtimeSetting({
|
|
|
10379
10379
|
"package": "himalaya",
|
|
10380
10380
|
"type": "Text",
|
|
10381
10381
|
"props": {
|
|
10382
|
-
"text": "Showing
|
|
10382
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
10383
10383
|
"style": "caption",
|
|
10384
10384
|
"color": "textSecondary"
|
|
10385
10385
|
}
|
|
@@ -13733,7 +13733,7 @@ const SCREENS = runtimeSetting({
|
|
|
13733
13733
|
"package": "himalaya",
|
|
13734
13734
|
"type": "Text",
|
|
13735
13735
|
"props": {
|
|
13736
|
-
"text": "Showing
|
|
13736
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
13737
13737
|
"style": "caption",
|
|
13738
13738
|
"color": "textSecondary"
|
|
13739
13739
|
}
|
|
@@ -17087,7 +17087,7 @@ const SCREENS = runtimeSetting({
|
|
|
17087
17087
|
"package": "himalaya",
|
|
17088
17088
|
"type": "Text",
|
|
17089
17089
|
"props": {
|
|
17090
|
-
"text": "Showing
|
|
17090
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
17091
17091
|
"style": "caption",
|
|
17092
17092
|
"color": "textSecondary"
|
|
17093
17093
|
}
|
|
@@ -20441,7 +20441,7 @@ const SCREENS = runtimeSetting({
|
|
|
20441
20441
|
"package": "himalaya",
|
|
20442
20442
|
"type": "Text",
|
|
20443
20443
|
"props": {
|
|
20444
|
-
"text": "Showing
|
|
20444
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
20445
20445
|
"style": "caption",
|
|
20446
20446
|
"color": "textSecondary"
|
|
20447
20447
|
}
|
|
@@ -23795,7 +23795,7 @@ const SCREENS = runtimeSetting({
|
|
|
23795
23795
|
"package": "himalaya",
|
|
23796
23796
|
"type": "Text",
|
|
23797
23797
|
"props": {
|
|
23798
|
-
"text": "Showing
|
|
23798
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
23799
23799
|
"style": "caption",
|
|
23800
23800
|
"color": "textSecondary"
|
|
23801
23801
|
}
|
|
@@ -27149,7 +27149,7 @@ const SCREENS = runtimeSetting({
|
|
|
27149
27149
|
"package": "himalaya",
|
|
27150
27150
|
"type": "Text",
|
|
27151
27151
|
"props": {
|
|
27152
|
-
"text": "Showing
|
|
27152
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
27153
27153
|
"style": "caption",
|
|
27154
27154
|
"color": "textSecondary"
|
|
27155
27155
|
}
|
|
@@ -30503,7 +30503,7 @@ const SCREENS = runtimeSetting({
|
|
|
30503
30503
|
"package": "himalaya",
|
|
30504
30504
|
"type": "Text",
|
|
30505
30505
|
"props": {
|
|
30506
|
-
"text": "Showing
|
|
30506
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
30507
30507
|
"style": "caption",
|
|
30508
30508
|
"color": "textSecondary"
|
|
30509
30509
|
}
|
|
@@ -33770,7 +33770,7 @@ const SCREENS = runtimeSetting({
|
|
|
33770
33770
|
"package": "himalaya",
|
|
33771
33771
|
"type": "Text",
|
|
33772
33772
|
"props": {
|
|
33773
|
-
"text": "Showing
|
|
33773
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
33774
33774
|
"style": "caption",
|
|
33775
33775
|
"color": "textSecondary"
|
|
33776
33776
|
}
|
|
@@ -36944,7 +36944,7 @@ const SCREENS = runtimeSetting({
|
|
|
36944
36944
|
"package": "himalaya",
|
|
36945
36945
|
"type": "Text",
|
|
36946
36946
|
"props": {
|
|
36947
|
-
"text": "Showing
|
|
36947
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
36948
36948
|
"style": "caption",
|
|
36949
36949
|
"color": "textSecondary"
|
|
36950
36950
|
}
|
|
@@ -40298,7 +40298,7 @@ const SCREENS = runtimeSetting({
|
|
|
40298
40298
|
"package": "himalaya",
|
|
40299
40299
|
"type": "Text",
|
|
40300
40300
|
"props": {
|
|
40301
|
-
"text": "Showing
|
|
40301
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
40302
40302
|
"style": "caption",
|
|
40303
40303
|
"color": "textSecondary"
|
|
40304
40304
|
}
|
|
@@ -43652,7 +43652,7 @@ const SCREENS = runtimeSetting({
|
|
|
43652
43652
|
"package": "himalaya",
|
|
43653
43653
|
"type": "Text",
|
|
43654
43654
|
"props": {
|
|
43655
|
-
"text": "Showing
|
|
43655
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
43656
43656
|
"style": "caption",
|
|
43657
43657
|
"color": "textSecondary"
|
|
43658
43658
|
}
|
|
@@ -46919,7 +46919,7 @@ const SCREENS = runtimeSetting({
|
|
|
46919
46919
|
"package": "himalaya",
|
|
46920
46920
|
"type": "Text",
|
|
46921
46921
|
"props": {
|
|
46922
|
-
"text": "Showing
|
|
46922
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
46923
46923
|
"style": "caption",
|
|
46924
46924
|
"color": "textSecondary"
|
|
46925
46925
|
}
|
|
@@ -68594,7 +68594,7 @@ const SCREENS = runtimeSetting({
|
|
|
68594
68594
|
"package": "himalaya",
|
|
68595
68595
|
"type": "Text",
|
|
68596
68596
|
"props": {
|
|
68597
|
-
"text": "Showing
|
|
68597
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
68598
68598
|
"style": "caption",
|
|
68599
68599
|
"color": "textSecondary"
|
|
68600
68600
|
}
|
|
@@ -71324,7 +71324,7 @@ const SCREENS = runtimeSetting({
|
|
|
71324
71324
|
"package": "himalaya",
|
|
71325
71325
|
"type": "Text",
|
|
71326
71326
|
"props": {
|
|
71327
|
-
"text": "Showing
|
|
71327
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
71328
71328
|
"style": "caption",
|
|
71329
71329
|
"color": "textSecondary"
|
|
71330
71330
|
}
|
|
@@ -73853,7 +73853,7 @@ const SCREENS = runtimeSetting({
|
|
|
73853
73853
|
"package": "himalaya",
|
|
73854
73854
|
"type": "Text",
|
|
73855
73855
|
"props": {
|
|
73856
|
-
"text": "Showing
|
|
73856
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
73857
73857
|
"style": "caption",
|
|
73858
73858
|
"color": "textSecondary"
|
|
73859
73859
|
}
|
|
@@ -76388,7 +76388,7 @@ const SCREENS = runtimeSetting({
|
|
|
76388
76388
|
"package": "himalaya",
|
|
76389
76389
|
"type": "Text",
|
|
76390
76390
|
"props": {
|
|
76391
|
-
"text": "Showing
|
|
76391
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
76392
76392
|
"style": "caption",
|
|
76393
76393
|
"color": "textSecondary"
|
|
76394
76394
|
}
|
|
@@ -79070,7 +79070,7 @@ const SCREENS = runtimeSetting({
|
|
|
79070
79070
|
"package": "himalaya",
|
|
79071
79071
|
"type": "Text",
|
|
79072
79072
|
"props": {
|
|
79073
|
-
"text": "Showing
|
|
79073
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
79074
79074
|
"style": "caption",
|
|
79075
79075
|
"color": "textSecondary"
|
|
79076
79076
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { withOnlineWrites } from './online-actions.js';
|
|
2
1
|
import { defineService as register, type ServiceDefinition } from '@himalaya/state';
|
|
3
2
|
import { COLLECTIONS, COLLECTION_CHROME_MIN_ITEMS, initialCollection, normalizeCollection, projectCollection, collectionId, collectionActionsLabel, type CollectionRow } from './collection-contract.js';
|
|
4
3
|
import { localPreferences, type PreferenceRuntime } from './local-preferences.js';
|
|
@@ -95,10 +94,7 @@ export function decorateCollection(name: string, def: { state: State; actions?:
|
|
|
95
94
|
if (sort === 'default' || sort === 'az' || sort === 'za') { prefs.sort = sort; changed = true; }
|
|
96
95
|
}
|
|
97
96
|
if (Object.prototype.hasOwnProperty.call(input, 'collectionFilter')) {
|
|
98
|
-
const
|
|
99
|
-
// Old links to Saved must migrate with the stored preference when this
|
|
100
|
-
// collection no longer exposes that filter.
|
|
101
|
-
const filter = config.rowStyle === 'flat' && requestedFilter === 'saved' ? 'all' : requestedFilter;
|
|
97
|
+
const filter = String(input.collectionFilter ?? '');
|
|
102
98
|
const configured = config.filterValues ?? [];
|
|
103
99
|
const rows = Array.isArray(state[config.rows]) ? state[config.rows] as CollectionRow[] : [];
|
|
104
100
|
const derived = config.filter ? rows.map(row => String(row[config.filter!] ?? '')).filter(Boolean) : [];
|
|
@@ -142,7 +138,7 @@ export function decorateCollection(name: string, def: { state: State; actions?:
|
|
|
142
138
|
copyParam('collection.itemActionsFor', 'Actions for {title}'), copyParam('collection.itemActions', 'Item actions'));
|
|
143
139
|
});
|
|
144
140
|
if (previewId && !rows.some(row => collectionId(row) === previewId)) previewId = '';
|
|
145
|
-
const filterChoices = [{ id: 'all', label: copyParam('collection.all', 'All') },
|
|
141
|
+
const filterChoices = [{ id: 'all', label: copyParam('collection.all', 'All') }, { id: 'saved', label: copyParam('collection.saved', 'Saved') },
|
|
146
142
|
...projected.filters.map(label => ({ id: `value:${label}`, label: copyParam(`collection.filter.${label}`, label) }))];
|
|
147
143
|
const loading = s.status === 'loading' || s.isLoading === true;
|
|
148
144
|
// Older domain reducers expose `errored` rather than `isErrored`; backend
|
|
@@ -223,7 +219,7 @@ export function decorateCollection(name: string, def: { state: State; actions?:
|
|
|
223
219
|
? [copyParam(`collection.${name}.countOne`, config.countNoun[0]), copyParam(`collection.${name}.countMany`, config.countNoun[1])] : undefined }),
|
|
224
220
|
selectedSummary: `${prefs.selectedIds.length} ${copyParam('collection.selected', 'selected')}`,
|
|
225
221
|
filterChoices,
|
|
226
|
-
chips: config.filterValues
|
|
222
|
+
chips: config.filterValues ? filterChoices.filter(choice => ['all', 'saved', prefs.filter].includes(choice.id)) : filterChoices,
|
|
227
223
|
} };
|
|
228
224
|
};
|
|
229
225
|
const actions: Record<string, Reducer> = {};
|
|
@@ -374,8 +370,9 @@ export function defineBackendCollection<S extends object, Row extends object>(na
|
|
|
374
370
|
controller: controller as unknown as BackendCollection['controller'],
|
|
375
371
|
apply: (state, page) => options.apply(state as S, page as unknown as CollectionQueryState<Row>) as State,
|
|
376
372
|
});
|
|
377
|
-
|
|
378
|
-
|
|
373
|
+
// Compatibility starters retain their existing mutation behavior; accept the
|
|
374
|
+
// current authoring contract without enabling the offline-write rollout.
|
|
375
|
+
const handle = (options.register ?? register)(name, definition);
|
|
379
376
|
// Registration restored the state a cold boot saved: the page it showed is this run's, before the first load. Only
|
|
380
377
|
// when the service's own rows came back with it: a bundle that keeps them out of the restore (its `notHydrated`)
|
|
381
378
|
// starts its first load as before, never from rows it chose not to restore. Rows that came back empty are the
|
|
@@ -45,7 +45,7 @@ const LIMIT = 50;
|
|
|
45
45
|
let zoneLookup: Promise<string | undefined> | undefined;
|
|
46
46
|
function siteZone(): Promise<string | undefined> {
|
|
47
47
|
// `Promise.resolve().then` so a bridge that throws synchronously is caught here too.
|
|
48
|
-
zoneLookup ??= Promise.resolve().then(getSiteTimeZone).catch(() => undefined);
|
|
48
|
+
zoneLookup ??= Promise.resolve().then(() => getSiteTimeZone()).catch(() => undefined);
|
|
49
49
|
return zoneLookup;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -6833,6 +6833,21 @@ const SCREENS = runtimeSetting({
|
|
|
6833
6833
|
}
|
|
6834
6834
|
}
|
|
6835
6835
|
},
|
|
6836
|
+
{
|
|
6837
|
+
"id": "",
|
|
6838
|
+
"body": {
|
|
6839
|
+
"package": "himalaya",
|
|
6840
|
+
"type": "Text",
|
|
6841
|
+
"props": {
|
|
6842
|
+
"text": "$service:himiBrandedShop.readMessage",
|
|
6843
|
+
"style": "body",
|
|
6844
|
+
"color": "textSecondary"
|
|
6845
|
+
}
|
|
6846
|
+
},
|
|
6847
|
+
"modifiers": {
|
|
6848
|
+
"hiddenPath": "$service:himiBrandedShop.noReadMessage"
|
|
6849
|
+
}
|
|
6850
|
+
},
|
|
6836
6851
|
{
|
|
6837
6852
|
"id": "",
|
|
6838
6853
|
"body": {
|
|
@@ -6843,6 +6858,9 @@ const SCREENS = runtimeSetting({
|
|
|
6843
6858
|
"style": "body",
|
|
6844
6859
|
"color": "textSecondary"
|
|
6845
6860
|
}
|
|
6861
|
+
},
|
|
6862
|
+
"modifiers": {
|
|
6863
|
+
"hiddenPath": "$service:himiBrandedShop.hasReadMessage"
|
|
6846
6864
|
}
|
|
6847
6865
|
},
|
|
6848
6866
|
{
|
|
@@ -18793,7 +18811,7 @@ const SCREENS = runtimeSetting({
|
|
|
18793
18811
|
"package": "himalaya",
|
|
18794
18812
|
"type": "Text",
|
|
18795
18813
|
"props": {
|
|
18796
|
-
"text": "Showing
|
|
18814
|
+
"text": "Showing previously loaded content · may be outdated",
|
|
18797
18815
|
"style": "caption",
|
|
18798
18816
|
"color": "textSecondary"
|
|
18799
18817
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { initialReadStatus, type ReadStatus } from '@himalaya/state';
|
|
2
|
+
|
|
3
|
+
/** Backend collection lifecycle shared by domain workers. The domain supplies
|
|
4
|
+
* the query and row mapper; this layer never calls a domain API or mutates it. */
|
|
5
|
+
export interface CollectionQuery {
|
|
6
|
+
query: string;
|
|
7
|
+
filter: string;
|
|
8
|
+
sort: 'default' | 'az' | 'za';
|
|
9
|
+
savedIds: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface CollectionPage<Row> {
|
|
12
|
+
items: Row[];
|
|
13
|
+
nextCursor: string;
|
|
14
|
+
total?: number;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
complete?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface CollectionQueryState<Row> extends CollectionPage<Row> {
|
|
19
|
+
criteria: CollectionQuery;
|
|
20
|
+
status: 'idle' | 'loading' | 'ready' | 'error';
|
|
21
|
+
loadingMore: boolean;
|
|
22
|
+
pageError: boolean;
|
|
23
|
+
complete: boolean;
|
|
24
|
+
error: string;
|
|
25
|
+
read: ReadStatus;
|
|
26
|
+
/** The rows are the source's `cached` page, shown while the live read is still out. */
|
|
27
|
+
provisional?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** What a collection showed, as `shownPage` hands it out and `seed` takes it back on a restored boot. */
|
|
30
|
+
export interface CollectionShownPage<Row> {
|
|
31
|
+
state: CollectionQueryState<Row>;
|
|
32
|
+
loadedPages: number;
|
|
33
|
+
}
|
|
34
|
+
export interface CollectionQuerySource<Row> {
|
|
35
|
+
fetch(criteria: CollectionQuery, cursor: string): Promise<CollectionPage<Row>>;
|
|
36
|
+
/** Optional public cache for immediate paint; always incomplete, never a paging authority. */
|
|
37
|
+
cached?(criteria: CollectionQuery): Promise<CollectionPage<Row> | undefined>;
|
|
38
|
+
id(row: Row): string;
|
|
39
|
+
errorMessage?(error: unknown): string;
|
|
40
|
+
/** Private collections must discard prior rows when access or identity changes. A revalidation keeps the
|
|
41
|
+
* rows it shows through any other failure: safe because one worker never serves two identities (its pool
|
|
42
|
+
* key carries the account, and a purge tears parked workers down). */
|
|
43
|
+
clearOnError?(error: unknown): boolean;
|
|
44
|
+
}
|
|
45
|
+
const normalize = (q: Partial<CollectionQuery>): CollectionQuery => ({
|
|
46
|
+
query: typeof q.query === 'string' ? q.query.trim().slice(0, 256) : '',
|
|
47
|
+
filter: typeof q.filter === 'string' ? q.filter.slice(0, 256) : 'all',
|
|
48
|
+
sort: q.sort === 'az' || q.sort === 'za' ? q.sort : 'default',
|
|
49
|
+
savedIds: Array.isArray(q.savedIds) ? [...new Set(q.savedIds.filter(id => typeof id === 'string' && id.length > 0 && id.length <= 256))].slice(0, 500) : [],
|
|
50
|
+
});
|
|
51
|
+
const copyQuery = (q: CollectionQuery): CollectionQuery => ({ ...q, savedIds: [...q.savedIds] });
|
|
52
|
+
|
|
53
|
+
/** New criteria cancel the old result logically, including an in-flight next
|
|
54
|
+
* page. Failures preserve the cursor and rows for an explicit retry. Callers
|
|
55
|
+
* publish each snapshot through their ordinary service reducer, so loading and
|
|
56
|
+
* filtered-empty never masquerade as a successfully completed query. */
|
|
57
|
+
export function createLegacyCollectionQuery<Row>(source: CollectionQuerySource<Row>, publish: (state: CollectionQueryState<Row>) => void) {
|
|
58
|
+
let generation = 0, disposed = false;
|
|
59
|
+
let loadedPages = 0, restoringPages = 0;
|
|
60
|
+
let state: CollectionQueryState<Row> = { criteria: normalize({}), items: [], nextCursor: '', status: 'idle', loadingMore: false, pageError: false, complete: false, error: '', read: initialReadStatus() };
|
|
61
|
+
/** The query a revalidation is running under: its snapshots are held back until it is done. */
|
|
62
|
+
let revalidating = -1;
|
|
63
|
+
/** The last page the screen showed whole (rows ready, nothing paging, failing or standing in): what a revalidation
|
|
64
|
+
* keeps on screen and restores when it fails, and what a restored boot shows. A next page loading or failing after
|
|
65
|
+
* it leaves those rows on screen, so it is still this. */
|
|
66
|
+
let lastShown: { state: CollectionQueryState<Row>; loadedPages: number } | undefined;
|
|
67
|
+
const sameCriteria = (a: CollectionQuery, b: CollectionQuery) => JSON.stringify(a) === JSON.stringify(b);
|
|
68
|
+
let clearedByError = false;
|
|
69
|
+
const snapshot = (): CollectionQueryState<Row> => ({ ...state, read: { ...state.read }, criteria: copyQuery(state.criteria), items: [...state.items] });
|
|
70
|
+
const emit = () => {
|
|
71
|
+
if (disposed || revalidating === generation) return;
|
|
72
|
+
// A settled answer replaces it, an empty one included: rows the live query proved gone are never kept.
|
|
73
|
+
if (state.status === 'ready' && !state.pageError && !state.loadingMore && !state.provisional) {
|
|
74
|
+
lastShown = { state: snapshot(), loadedPages };
|
|
75
|
+
}
|
|
76
|
+
publish(snapshot());
|
|
77
|
+
};
|
|
78
|
+
const merge = (old: Row[], page: Row[]): Row[] => {
|
|
79
|
+
const positions = new Map<string, number>(), result: Row[] = [];
|
|
80
|
+
for (const item of [...old, ...page]) {
|
|
81
|
+
const id = source.id(item);
|
|
82
|
+
if (!id) throw new Error('A backend collection row requires an identity');
|
|
83
|
+
const index = positions.get(id);
|
|
84
|
+
if (index === undefined) { positions.set(id, result.length); result.push(item); }
|
|
85
|
+
else result[index] = item;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
/** [keepRows]: a search typed over the rows on screen leaves them there until its answer arrives (status stays
|
|
90
|
+
* `loading`, and nothing pages under the old answer), so the list is not blanked on each keystroke. */
|
|
91
|
+
const fetch = async (append: boolean, keepRows = false): Promise<void> => {
|
|
92
|
+
if (disposed || (append && (state.loadingMore || state.status === 'loading' || !state.nextCursor))) return;
|
|
93
|
+
const revision = append ? generation : ++generation;
|
|
94
|
+
const cursor = append ? state.nextCursor : '';
|
|
95
|
+
const criteria = copyQuery(state.criteria);
|
|
96
|
+
if (!append) loadedPages = 0;
|
|
97
|
+
state = { ...state, status: append ? 'ready' : 'loading', loadingMore: append, pageError: false, error: '',
|
|
98
|
+
...(append ? {} : keepRows ? { nextCursor: '', complete: false, provisional: false }
|
|
99
|
+
: { items: [], nextCursor: '', total: undefined, metadata: undefined, complete: false, provisional: false }) };
|
|
100
|
+
emit();
|
|
101
|
+
try {
|
|
102
|
+
if (!append && source.cached) {
|
|
103
|
+
const cached = await source.cached(criteria).catch(() => undefined);
|
|
104
|
+
if (disposed || generation !== revision) return;
|
|
105
|
+
if (cached?.items.length) {
|
|
106
|
+
state = { ...state, items: merge([], cached.items), metadata: cached.metadata, status: 'ready', complete: false, provisional: true };
|
|
107
|
+
emit();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const page = await source.fetch(criteria, cursor);
|
|
111
|
+
if (disposed || generation !== revision) return;
|
|
112
|
+
if (!Array.isArray(page.items) || typeof page.nextCursor !== 'string' || (cursor && page.nextCursor === cursor)) throw new Error('Invalid collection page');
|
|
113
|
+
state = { ...state, items: merge(append ? state.items : [], page.items), nextCursor: page.nextCursor,
|
|
114
|
+
total: typeof page.total === 'number' && Number.isFinite(page.total) && page.total >= 0 ? page.total : (append ? state.total : undefined),
|
|
115
|
+
metadata: page.metadata ?? (append ? state.metadata : undefined),
|
|
116
|
+
status: 'ready', loadingMore: false, pageError: false, complete: page.complete ?? !page.nextCursor, provisional: false };
|
|
117
|
+
loadedPages++;
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (disposed || generation !== revision) return;
|
|
120
|
+
const clear = source.clearOnError?.(error) === true;
|
|
121
|
+
// Revoked access always ends what a revalidation showed, whether or not the source clears its rows.
|
|
122
|
+
clearedByError = clear || /HTTP 40[13]\b/.test(String(error));
|
|
123
|
+
if (clearedByError) lastShown = undefined;
|
|
124
|
+
if (clear) loadedPages = 0;
|
|
125
|
+
// The rows a typed search kept on screen while it ran were never its answer: a failed one shows none of them.
|
|
126
|
+
const drop = clear || keepRows;
|
|
127
|
+
state = { ...state, ...(drop ? { items: [], nextCursor: '', total: undefined, metadata: undefined } : {}),
|
|
128
|
+
status: append && !clear ? 'ready' : 'error', loadingMore: false, pageError: append && !clear, complete: false,
|
|
129
|
+
provisional: false, error: source.errorMessage?.(error) ?? '' };
|
|
130
|
+
}
|
|
131
|
+
emit();
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
getState: snapshot,
|
|
135
|
+
/** [revalidate]: a screen coming back re-queries the rows it shows. They stay on screen until every
|
|
136
|
+
* page is in, and a failure keeps them; revoked access still clears them, and other criteria reset. */
|
|
137
|
+
async query(criteria: Partial<CollectionQuery>, restorePages = false, revalidate = false): Promise<void> {
|
|
138
|
+
if (disposed) return Promise.resolve();
|
|
139
|
+
const next = normalize(criteria);
|
|
140
|
+
const same = JSON.stringify(next) === JSON.stringify(state.criteria);
|
|
141
|
+
const count = restorePages && same ? Math.max(loadedPages, restoringPages, 1) : 1;
|
|
142
|
+
const showing = lastShown && sameCriteria(lastShown.state.criteria, next) ? lastShown : undefined;
|
|
143
|
+
restoringPages = count;
|
|
144
|
+
// Only the search text changed: the user is typing over the rows on screen, also while the last keystroke's
|
|
145
|
+
// search is still out.
|
|
146
|
+
const typing = !same && (state.status === 'ready' || state.status === 'loading')
|
|
147
|
+
&& sameCriteria({ ...state.criteria, query: '' }, { ...next, query: '' });
|
|
148
|
+
state = { ...state, criteria: next };
|
|
149
|
+
if (revalidate && showing) { revalidating = generation + 1; clearedByError = false; }
|
|
150
|
+
const pending = fetch(false, typing);
|
|
151
|
+
const revision = generation;
|
|
152
|
+
await pending;
|
|
153
|
+
// Re-appearance revalidates every previously opened page using fresh
|
|
154
|
+
// cursors. A changed query, error or revoked access stops the restoration.
|
|
155
|
+
while (!disposed && generation === revision && loadedPages < count && state.status === 'ready'
|
|
156
|
+
&& !state.pageError && !state.loadingMore && state.nextCursor) await fetch(true);
|
|
157
|
+
if (generation === revision) restoringPages = 0;
|
|
158
|
+
if (revalidating === revision) {
|
|
159
|
+
revalidating = -1;
|
|
160
|
+
if (generation !== revision) return;
|
|
161
|
+
if ((state.status !== 'ready' || state.pageError) && showing && !clearedByError) {
|
|
162
|
+
state = { ...showing.state, criteria: next };
|
|
163
|
+
loadedPages = showing.loadedPages;
|
|
164
|
+
}
|
|
165
|
+
emit();
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
/** The page the screen shows (rows ready, nothing failing or still paging), for the service to keep with its
|
|
169
|
+
* state; undefined when it shows none. */
|
|
170
|
+
shownPage(): CollectionShownPage<Row> | undefined {
|
|
171
|
+
if (!lastShown || !sameCriteria(lastShown.state.criteria, state.criteria)) return undefined;
|
|
172
|
+
const page = lastShown.state;
|
|
173
|
+
return { state: { ...page, criteria: copyQuery(page.criteria), items: [...page.items] }, loadedPages: lastShown.loadedPages };
|
|
174
|
+
},
|
|
175
|
+
/** A cold boot restored from disk: what the last run showed becomes what this one shows, so its first `load`
|
|
176
|
+
* revalidates behind it instead of starting empty. Only before the first query, and only a well-formed page. */
|
|
177
|
+
seed(page: unknown): boolean {
|
|
178
|
+
const candidate = page && typeof page === 'object' ? page as Partial<CollectionShownPage<Row>> : undefined;
|
|
179
|
+
const restored = candidate?.state;
|
|
180
|
+
if (generation !== 0 || state.status !== 'idle' || !restored || restored.status !== 'ready'
|
|
181
|
+
|| !Array.isArray(restored.items) || typeof restored.nextCursor !== 'string') return false;
|
|
182
|
+
try { restored.items.forEach(item => { if (!source.id(item)) throw new Error('A backend collection row requires an identity'); }); } catch { return false; }
|
|
183
|
+
state = { ...state, ...restored, criteria: normalize(restored.criteria ?? {}), items: [...restored.items], status: 'ready',
|
|
184
|
+
loadingMore: false, pageError: false, provisional: false, error: '', read: restored.read ? { ...restored.read } : initialReadStatus() };
|
|
185
|
+
loadedPages = Math.max(1, Math.floor(Number(candidate?.loadedPages) || 1));
|
|
186
|
+
lastShown = { state: snapshot(), loadedPages };
|
|
187
|
+
return true;
|
|
188
|
+
},
|
|
189
|
+
refresh: () => { restoringPages = 0; return fetch(false); },
|
|
190
|
+
loadMore: () => fetch(true),
|
|
191
|
+
retry: () => fetch(state.pageError),
|
|
192
|
+
dispose() { disposed = true; generation++; },
|
|
193
|
+
};
|
|
194
|
+
}
|