@aglyn/aglyn 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +11 -0
- package/package.json +66 -0
- package/src/index.d.ts +25 -0
- package/src/index.js +26 -0
- package/src/index.js.map +1 -0
- package/src/lib/aglyn.d.ts +31 -0
- package/src/lib/aglyn.js +114 -0
- package/src/lib/aglyn.js.map +1 -0
- package/src/lib/app-utils/abuse-report.d.ts +193 -0
- package/src/lib/app-utils/abuse-report.js +321 -0
- package/src/lib/app-utils/abuse-report.js.map +1 -0
- package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
- package/src/lib/app-utils/accept-negotiation.js +266 -0
- package/src/lib/app-utils/accept-negotiation.js.map +1 -0
- package/src/lib/app-utils/account-emails.d.ts +263 -0
- package/src/lib/app-utils/account-emails.js +264 -0
- package/src/lib/app-utils/account-emails.js.map +1 -0
- package/src/lib/app-utils/actions.d.ts +717 -0
- package/src/lib/app-utils/actions.js +1031 -0
- package/src/lib/app-utils/actions.js.map +1 -0
- package/src/lib/app-utils/activity-presenter.d.ts +152 -0
- package/src/lib/app-utils/activity-presenter.js +326 -0
- package/src/lib/app-utils/activity-presenter.js.map +1 -0
- package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
- package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
- package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
- package/src/lib/app-utils/advertising-tags.d.ts +307 -0
- package/src/lib/app-utils/advertising-tags.js +525 -0
- package/src/lib/app-utils/advertising-tags.js.map +1 -0
- package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
- package/src/lib/app-utils/agent-api-catalog.js +106 -0
- package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
- package/src/lib/app-utils/agent-openapi.d.ts +103 -0
- package/src/lib/app-utils/agent-openapi.js +1128 -0
- package/src/lib/app-utils/agent-openapi.js.map +1 -0
- package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
- package/src/lib/app-utils/analytics-beacon.js +152 -0
- package/src/lib/app-utils/analytics-beacon.js.map +1 -0
- package/src/lib/app-utils/analytics-environment.d.ts +133 -0
- package/src/lib/app-utils/analytics-environment.js +152 -0
- package/src/lib/app-utils/analytics-environment.js.map +1 -0
- package/src/lib/app-utils/analytics-events.d.ts +744 -0
- package/src/lib/app-utils/analytics-events.js +650 -0
- package/src/lib/app-utils/analytics-events.js.map +1 -0
- package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
- package/src/lib/app-utils/analytics-link-clicks.js +267 -0
- package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
- package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
- package/src/lib/app-utils/analytics-path-key.js +46 -0
- package/src/lib/app-utils/analytics-path-key.js.map +1 -0
- package/src/lib/app-utils/api-adapter.d.ts +47 -0
- package/src/lib/app-utils/api-adapter.js +367 -0
- package/src/lib/app-utils/api-adapter.js.map +1 -0
- package/src/lib/app-utils/api-idempotency.d.ts +169 -0
- package/src/lib/app-utils/api-idempotency.js +213 -0
- package/src/lib/app-utils/api-idempotency.js.map +1 -0
- package/src/lib/app-utils/api-plugins.d.ts +210 -0
- package/src/lib/app-utils/api-plugins.js +221 -0
- package/src/lib/app-utils/api-plugins.js.map +1 -0
- package/src/lib/app-utils/assist-credits.d.ts +482 -0
- package/src/lib/app-utils/assist-credits.js +509 -0
- package/src/lib/app-utils/assist-credits.js.map +1 -0
- package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
- package/src/lib/app-utils/attribution-attribute.js +34 -0
- package/src/lib/app-utils/attribution-attribute.js.map +1 -0
- package/src/lib/app-utils/attribution-guard.d.ts +130 -0
- package/src/lib/app-utils/attribution-guard.js +410 -0
- package/src/lib/app-utils/attribution-guard.js.map +1 -0
- package/src/lib/app-utils/author-css.d.ts +123 -0
- package/src/lib/app-utils/author-css.js +275 -0
- package/src/lib/app-utils/author-css.js.map +1 -0
- package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
- package/src/lib/app-utils/author-html-markdown.js +497 -0
- package/src/lib/app-utils/author-html-markdown.js.map +1 -0
- package/src/lib/app-utils/author-html.d.ts +135 -0
- package/src/lib/app-utils/author-html.js +1037 -0
- package/src/lib/app-utils/author-html.js.map +1 -0
- package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
- package/src/lib/app-utils/automation-placeholders.js +207 -0
- package/src/lib/app-utils/automation-placeholders.js.map +1 -0
- package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
- package/src/lib/app-utils/bandwidth-cap.js +193 -0
- package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
- package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
- package/src/lib/app-utils/binding-token-catalog.js +293 -0
- package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
- package/src/lib/app-utils/binding-tokens.d.ts +157 -0
- package/src/lib/app-utils/binding-tokens.js +251 -0
- package/src/lib/app-utils/binding-tokens.js.map +1 -0
- package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
- package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
- package/src/lib/app-utils/campaign-attribution.js +162 -0
- package/src/lib/app-utils/campaign-attribution.js.map +1 -0
- package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
- package/src/lib/app-utils/campaign-forwarding.js +332 -0
- package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
- package/src/lib/app-utils/campaign-membership.d.ts +109 -0
- package/src/lib/app-utils/campaign-membership.js +176 -0
- package/src/lib/app-utils/campaign-membership.js.map +1 -0
- package/src/lib/app-utils/campaign-touch.d.ts +206 -0
- package/src/lib/app-utils/campaign-touch.js +326 -0
- package/src/lib/app-utils/campaign-touch.js.map +1 -0
- package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
- package/src/lib/app-utils/child-contract-compose.js +140 -0
- package/src/lib/app-utils/child-contract-compose.js.map +1 -0
- package/src/lib/app-utils/child-contract.d.ts +129 -0
- package/src/lib/app-utils/child-contract.js +153 -0
- package/src/lib/app-utils/child-contract.js.map +1 -0
- package/src/lib/app-utils/collection-delete.d.ts +113 -0
- package/src/lib/app-utils/collection-delete.js +120 -0
- package/src/lib/app-utils/collection-delete.js.map +1 -0
- package/src/lib/app-utils/collection-entries.d.ts +833 -0
- package/src/lib/app-utils/collection-entries.js +1285 -0
- package/src/lib/app-utils/collection-entries.js.map +1 -0
- package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
- package/src/lib/app-utils/collection-entry-date.js +183 -0
- package/src/lib/app-utils/collection-entry-date.js.map +1 -0
- package/src/lib/app-utils/collection-kind.d.ts +55 -0
- package/src/lib/app-utils/collection-kind.js +69 -0
- package/src/lib/app-utils/collection-kind.js.map +1 -0
- package/src/lib/app-utils/collection-slug.d.ts +79 -0
- package/src/lib/app-utils/collection-slug.js +70 -0
- package/src/lib/app-utils/collection-slug.js.map +1 -0
- package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
- package/src/lib/app-utils/compose-layout-nodes.js +261 -0
- package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
- package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
- package/src/lib/app-utils/compose-layout-props.js +61 -0
- package/src/lib/app-utils/compose-layout-props.js.map +1 -0
- package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
- package/src/lib/app-utils/compose-reusable-components.js +1366 -0
- package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
- package/src/lib/app-utils/compress.d.ts +35 -0
- package/src/lib/app-utils/compress.js +38 -0
- package/src/lib/app-utils/compress.js.map +1 -0
- package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
- package/src/lib/app-utils/consent-banner-ui.js +583 -0
- package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
- package/src/lib/app-utils/consent-groups.d.ts +189 -0
- package/src/lib/app-utils/consent-groups.js +219 -0
- package/src/lib/app-utils/consent-groups.js.map +1 -0
- package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
- package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
- package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
- package/src/lib/app-utils/console-record-links.d.ts +163 -0
- package/src/lib/app-utils/console-record-links.js +178 -0
- package/src/lib/app-utils/console-record-links.js.map +1 -0
- package/src/lib/app-utils/console-routes.d.ts +658 -0
- package/src/lib/app-utils/console-routes.js +489 -0
- package/src/lib/app-utils/console-routes.js.map +1 -0
- package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
- package/src/lib/app-utils/console-widget-slot-context.js +23 -0
- package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
- package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
- package/src/lib/app-utils/contact-custom-fields.js +349 -0
- package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
- package/src/lib/app-utils/contact-holder.d.ts +52 -0
- package/src/lib/app-utils/contact-holder.js +98 -0
- package/src/lib/app-utils/contact-holder.js.map +1 -0
- package/src/lib/app-utils/contact-merge.d.ts +136 -0
- package/src/lib/app-utils/contact-merge.js +379 -0
- package/src/lib/app-utils/contact-merge.js.map +1 -0
- package/src/lib/app-utils/contacts.d.ts +554 -0
- package/src/lib/app-utils/contacts.js +401 -0
- package/src/lib/app-utils/contacts.js.map +1 -0
- package/src/lib/app-utils/content-author-profile.d.ts +68 -0
- package/src/lib/app-utils/content-author-profile.js +118 -0
- package/src/lib/app-utils/content-author-profile.js.map +1 -0
- package/src/lib/app-utils/content-authors.d.ts +662 -0
- package/src/lib/app-utils/content-authors.js +771 -0
- package/src/lib/app-utils/content-authors.js.map +1 -0
- package/src/lib/app-utils/content-schema-type.d.ts +81 -0
- package/src/lib/app-utils/content-schema-type.js +87 -0
- package/src/lib/app-utils/content-schema-type.js.map +1 -0
- package/src/lib/app-utils/contexts.d.ts +35 -0
- package/src/lib/app-utils/contexts.js +35 -0
- package/src/lib/app-utils/contexts.js.map +1 -0
- package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
- package/src/lib/app-utils/create-resource-uid.js +23 -0
- package/src/lib/app-utils/create-resource-uid.js.map +1 -0
- package/src/lib/app-utils/crm-booking.d.ts +75 -0
- package/src/lib/app-utils/crm-booking.js +133 -0
- package/src/lib/app-utils/crm-booking.js.map +1 -0
- package/src/lib/app-utils/crm-csv.d.ts +232 -0
- package/src/lib/app-utils/crm-csv.js +432 -0
- package/src/lib/app-utils/crm-csv.js.map +1 -0
- package/src/lib/app-utils/crm-digest.d.ts +179 -0
- package/src/lib/app-utils/crm-digest.js +271 -0
- package/src/lib/app-utils/crm-digest.js.map +1 -0
- package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
- package/src/lib/app-utils/crm-email-templates.js +382 -0
- package/src/lib/app-utils/crm-email-templates.js.map +1 -0
- package/src/lib/app-utils/crm-inbound.d.ts +245 -0
- package/src/lib/app-utils/crm-inbound.js +407 -0
- package/src/lib/app-utils/crm-inbound.js.map +1 -0
- package/src/lib/app-utils/crm-kinds.d.ts +73 -0
- package/src/lib/app-utils/crm-kinds.js +92 -0
- package/src/lib/app-utils/crm-kinds.js.map +1 -0
- package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
- package/src/lib/app-utils/crm-next-activity.js +140 -0
- package/src/lib/app-utils/crm-next-activity.js.map +1 -0
- package/src/lib/app-utils/crm-reports.d.ts +479 -0
- package/src/lib/app-utils/crm-reports.js +680 -0
- package/src/lib/app-utils/crm-reports.js.map +1 -0
- package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
- package/src/lib/app-utils/crm-task-reminders.js +139 -0
- package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
- package/src/lib/app-utils/crm.d.ts +1546 -0
- package/src/lib/app-utils/crm.js +1814 -0
- package/src/lib/app-utils/crm.js.map +1 -0
- package/src/lib/app-utils/csp-report.d.ts +84 -0
- package/src/lib/app-utils/csp-report.js +177 -0
- package/src/lib/app-utils/csp-report.js.map +1 -0
- package/src/lib/app-utils/csv-import.d.ts +192 -0
- package/src/lib/app-utils/csv-import.js +279 -0
- package/src/lib/app-utils/csv-import.js.map +1 -0
- package/src/lib/app-utils/dataset-csv.d.ts +109 -0
- package/src/lib/app-utils/dataset-csv.js +235 -0
- package/src/lib/app-utils/dataset-csv.js.map +1 -0
- package/src/lib/app-utils/dataset-models.d.ts +194 -0
- package/src/lib/app-utils/dataset-models.js +409 -0
- package/src/lib/app-utils/dataset-models.js.map +1 -0
- package/src/lib/app-utils/dataset-query.d.ts +57 -0
- package/src/lib/app-utils/dataset-query.js +126 -0
- package/src/lib/app-utils/dataset-query.js.map +1 -0
- package/src/lib/app-utils/datasets.d.ts +136 -0
- package/src/lib/app-utils/datasets.js +177 -0
- package/src/lib/app-utils/datasets.js.map +1 -0
- package/src/lib/app-utils/decompress.d.ts +36 -0
- package/src/lib/app-utils/decompress.js +32 -0
- package/src/lib/app-utils/decompress.js.map +1 -0
- package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
- package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
- package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
- package/src/lib/app-utils/deferred-image.d.ts +86 -0
- package/src/lib/app-utils/deferred-image.js +83 -0
- package/src/lib/app-utils/deferred-image.js.map +1 -0
- package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
- package/src/lib/app-utils/definition-canvas-tree.js +126 -0
- package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
- package/src/lib/app-utils/deployment-shape.d.ts +167 -0
- package/src/lib/app-utils/deployment-shape.js +238 -0
- package/src/lib/app-utils/deployment-shape.js.map +1 -0
- package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
- package/src/lib/app-utils/detect-template-placeholders.js +53 -0
- package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
- package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
- package/src/lib/app-utils/dmca-counter-notice.js +277 -0
- package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
- package/src/lib/app-utils/docs-deflection.d.ts +156 -0
- package/src/lib/app-utils/docs-deflection.js +547 -0
- package/src/lib/app-utils/docs-deflection.js.map +1 -0
- package/src/lib/app-utils/docs-help.d.ts +57 -0
- package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
- package/src/lib/app-utils/docs-help.generated.js +867 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -0
- package/src/lib/app-utils/docs-help.js +46 -0
- package/src/lib/app-utils/docs-help.js.map +1 -0
- package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
- package/src/lib/app-utils/docs-index.generated.js +8388 -0
- package/src/lib/app-utils/docs-index.generated.js.map +1 -0
- package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
- package/src/lib/app-utils/docs-retrieval.js +188 -0
- package/src/lib/app-utils/docs-retrieval.js.map +1 -0
- package/src/lib/app-utils/document-landmark.d.ts +50 -0
- package/src/lib/app-utils/document-landmark.js +100 -0
- package/src/lib/app-utils/document-landmark.js.map +1 -0
- package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
- package/src/lib/app-utils/duplicate-resource.js +206 -0
- package/src/lib/app-utils/duplicate-resource.js.map +1 -0
- package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
- package/src/lib/app-utils/dynamic-list-rule.js +914 -0
- package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
- package/src/lib/app-utils/element-animation.d.ts +200 -0
- package/src/lib/app-utils/element-animation.js +233 -0
- package/src/lib/app-utils/element-animation.js.map +1 -0
- package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
- package/src/lib/app-utils/element-hidden-style.js +48 -0
- package/src/lib/app-utils/element-hidden-style.js.map +1 -0
- package/src/lib/app-utils/element-ui.d.ts +243 -0
- package/src/lib/app-utils/element-ui.js +459 -0
- package/src/lib/app-utils/element-ui.js.map +1 -0
- package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
- package/src/lib/app-utils/email-starter-policy.js +327 -0
- package/src/lib/app-utils/email-starter-policy.js.map +1 -0
- package/src/lib/app-utils/email-topics.d.ts +310 -0
- package/src/lib/app-utils/email-topics.js +336 -0
- package/src/lib/app-utils/email-topics.js.map +1 -0
- package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
- package/src/lib/app-utils/enabled-plugins-context.js +113 -0
- package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
- package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
- package/src/lib/app-utils/ensure-canvas-root.js +61 -0
- package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
- package/src/lib/app-utils/entity-picker-context.js +93 -0
- package/src/lib/app-utils/entity-picker-context.js.map +1 -0
- package/src/lib/app-utils/error-beacon.d.ts +107 -0
- package/src/lib/app-utils/error-beacon.js +296 -0
- package/src/lib/app-utils/error-beacon.js.map +1 -0
- package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
- package/src/lib/app-utils/expand-repeatables.js +299 -0
- package/src/lib/app-utils/expand-repeatables.js.map +1 -0
- package/src/lib/app-utils/foreign-script.d.ts +82 -0
- package/src/lib/app-utils/foreign-script.js +102 -0
- package/src/lib/app-utils/foreign-script.js.map +1 -0
- package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
- package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
- package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
- package/src/lib/app-utils/form-contract.d.ts +198 -0
- package/src/lib/app-utils/form-contract.js +282 -0
- package/src/lib/app-utils/form-contract.js.map +1 -0
- package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
- package/src/lib/app-utils/form-dataset-binding.js +74 -0
- package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
- package/src/lib/app-utils/forms.d.ts +727 -0
- package/src/lib/app-utils/forms.js +777 -0
- package/src/lib/app-utils/forms.js.map +1 -0
- package/src/lib/app-utils/functions.d.ts +188 -0
- package/src/lib/app-utils/functions.js +529 -0
- package/src/lib/app-utils/functions.js.map +1 -0
- package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
- package/src/lib/app-utils/guarded-version-save.js +131 -0
- package/src/lib/app-utils/guarded-version-save.js.map +1 -0
- package/src/lib/app-utils/health-report.d.ts +1766 -0
- package/src/lib/app-utils/health-report.js +2072 -0
- package/src/lib/app-utils/health-report.js.map +1 -0
- package/src/lib/app-utils/host-naming.d.ts +135 -0
- package/src/lib/app-utils/host-naming.js +188 -0
- package/src/lib/app-utils/host-naming.js.map +1 -0
- package/src/lib/app-utils/host-permissions.d.ts +76 -0
- package/src/lib/app-utils/host-permissions.js +119 -0
- package/src/lib/app-utils/host-permissions.js.map +1 -0
- package/src/lib/app-utils/host-tokens.d.ts +228 -0
- package/src/lib/app-utils/host-tokens.js +304 -0
- package/src/lib/app-utils/host-tokens.js.map +1 -0
- package/src/lib/app-utils/idp-profile.d.ts +83 -0
- package/src/lib/app-utils/idp-profile.js +268 -0
- package/src/lib/app-utils/idp-profile.js.map +1 -0
- package/src/lib/app-utils/image-upload-types.d.ts +49 -0
- package/src/lib/app-utils/image-upload-types.js +86 -0
- package/src/lib/app-utils/image-upload-types.js.map +1 -0
- package/src/lib/app-utils/index.d.ts +18 -0
- package/src/lib/app-utils/index.js +23 -0
- package/src/lib/app-utils/index.js.map +1 -0
- package/src/lib/app-utils/internal-traffic.d.ts +197 -0
- package/src/lib/app-utils/internal-traffic.js +288 -0
- package/src/lib/app-utils/internal-traffic.js.map +1 -0
- package/src/lib/app-utils/lineal-order.d.ts +62 -0
- package/src/lib/app-utils/lineal-order.js +65 -0
- package/src/lib/app-utils/lineal-order.js.map +1 -0
- package/src/lib/app-utils/link-references.d.ts +36 -0
- package/src/lib/app-utils/link-references.js +89 -0
- package/src/lib/app-utils/link-references.js.map +1 -0
- package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
- package/src/lib/app-utils/link-target-search-context.js +221 -0
- package/src/lib/app-utils/link-target-search-context.js.map +1 -0
- package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
- package/src/lib/app-utils/list-assignment-policy.js +170 -0
- package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
- package/src/lib/app-utils/list-import.d.ts +158 -0
- package/src/lib/app-utils/list-import.js +332 -0
- package/src/lib/app-utils/list-import.js.map +1 -0
- package/src/lib/app-utils/llms-txt.d.ts +104 -0
- package/src/lib/app-utils/llms-txt.js +144 -0
- package/src/lib/app-utils/llms-txt.js.map +1 -0
- package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
- package/src/lib/app-utils/local-storage-budget.js +153 -0
- package/src/lib/app-utils/local-storage-budget.js.map +1 -0
- package/src/lib/app-utils/lockdown.d.ts +698 -0
- package/src/lib/app-utils/lockdown.js +929 -0
- package/src/lib/app-utils/lockdown.js.map +1 -0
- package/src/lib/app-utils/margin-utilization.d.ts +267 -0
- package/src/lib/app-utils/margin-utilization.js +351 -0
- package/src/lib/app-utils/margin-utilization.js.map +1 -0
- package/src/lib/app-utils/markdown-lite.d.ts +297 -0
- package/src/lib/app-utils/markdown-lite.js +705 -0
- package/src/lib/app-utils/markdown-lite.js.map +1 -0
- package/src/lib/app-utils/marketing-consent.d.ts +704 -0
- package/src/lib/app-utils/marketing-consent.js +783 -0
- package/src/lib/app-utils/marketing-consent.js.map +1 -0
- package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
- package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
- package/src/lib/app-utils/marketplace-overrides.js +462 -0
- package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
- package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
- package/src/lib/app-utils/marketplace-provenance.js +136 -0
- package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
- package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
- package/src/lib/app-utils/marketplace-theme.js +525 -0
- package/src/lib/app-utils/marketplace-theme.js.map +1 -0
- package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
- package/src/lib/app-utils/marketplace-update-state.js +132 -0
- package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
- package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
- package/src/lib/app-utils/marketplace-verification.js +81 -0
- package/src/lib/app-utils/marketplace-verification.js.map +1 -0
- package/src/lib/app-utils/measure-node-map.d.ts +76 -0
- package/src/lib/app-utils/measure-node-map.js +111 -0
- package/src/lib/app-utils/measure-node-map.js.map +1 -0
- package/src/lib/app-utils/media-alt.d.ts +55 -0
- package/src/lib/app-utils/media-alt.js +58 -0
- package/src/lib/app-utils/media-alt.js.map +1 -0
- package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
- package/src/lib/app-utils/media-asset-facts.js +467 -0
- package/src/lib/app-utils/media-asset-facts.js.map +1 -0
- package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
- package/src/lib/app-utils/media-cdn-scope.js +75 -0
- package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
- package/src/lib/app-utils/media-folders.d.ts +161 -0
- package/src/lib/app-utils/media-folders.js +230 -0
- package/src/lib/app-utils/media-folders.js.map +1 -0
- package/src/lib/app-utils/media-metadata.d.ts +277 -0
- package/src/lib/app-utils/media-metadata.js +388 -0
- package/src/lib/app-utils/media-metadata.js.map +1 -0
- package/src/lib/app-utils/media-picker-context.d.ts +93 -0
- package/src/lib/app-utils/media-picker-context.js +26 -0
- package/src/lib/app-utils/media-picker-context.js.map +1 -0
- package/src/lib/app-utils/media-quarantine.d.ts +247 -0
- package/src/lib/app-utils/media-quarantine.js +323 -0
- package/src/lib/app-utils/media-quarantine.js.map +1 -0
- package/src/lib/app-utils/media-ref.d.ts +661 -0
- package/src/lib/app-utils/media-ref.js +1055 -0
- package/src/lib/app-utils/media-ref.js.map +1 -0
- package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
- package/src/lib/app-utils/media-takedown-reach.js +143 -0
- package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
- package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
- package/src/lib/app-utils/member-email-aliases.js +217 -0
- package/src/lib/app-utils/member-email-aliases.js.map +1 -0
- package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
- package/src/lib/app-utils/merge-node-sx.js +123 -0
- package/src/lib/app-utils/merge-node-sx.js.map +1 -0
- package/src/lib/app-utils/name-match.d.ts +155 -0
- package/src/lib/app-utils/name-match.js +175 -0
- package/src/lib/app-utils/name-match.js.map +1 -0
- package/src/lib/app-utils/name-search.d.ts +117 -0
- package/src/lib/app-utils/name-search.js +145 -0
- package/src/lib/app-utils/name-search.js.map +1 -0
- package/src/lib/app-utils/node-capabilities.d.ts +85 -0
- package/src/lib/app-utils/node-capabilities.js +88 -0
- package/src/lib/app-utils/node-capabilities.js.map +1 -0
- package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
- package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
- package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
- package/src/lib/app-utils/node-identity.d.ts +47 -0
- package/src/lib/app-utils/node-identity.js +50 -0
- package/src/lib/app-utils/node-identity.js.map +1 -0
- package/src/lib/app-utils/node-interactions.d.ts +102 -0
- package/src/lib/app-utils/node-interactions.js +192 -0
- package/src/lib/app-utils/node-interactions.js.map +1 -0
- package/src/lib/app-utils/node-url-policy.d.ts +54 -0
- package/src/lib/app-utils/node-url-policy.js +72 -0
- package/src/lib/app-utils/node-url-policy.js.map +1 -0
- package/src/lib/app-utils/notifications.d.ts +71 -0
- package/src/lib/app-utils/notifications.js +101 -0
- package/src/lib/app-utils/notifications.js.map +1 -0
- package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
- package/src/lib/app-utils/onboarding-deep-link.js +142 -0
- package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
- package/src/lib/app-utils/operator-identity.d.ts +207 -0
- package/src/lib/app-utils/operator-identity.js +186 -0
- package/src/lib/app-utils/operator-identity.js.map +1 -0
- package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
- package/src/lib/app-utils/org-billing-doc.js +238 -0
- package/src/lib/app-utils/org-billing-doc.js.map +1 -0
- package/src/lib/app-utils/org-override-reason.d.ts +100 -0
- package/src/lib/app-utils/org-override-reason.js +116 -0
- package/src/lib/app-utils/org-override-reason.js.map +1 -0
- package/src/lib/app-utils/org-permissions.d.ts +194 -0
- package/src/lib/app-utils/org-permissions.js +357 -0
- package/src/lib/app-utils/org-permissions.js.map +1 -0
- package/src/lib/app-utils/org-roles.d.ts +72 -0
- package/src/lib/app-utils/org-roles.js +131 -0
- package/src/lib/app-utils/org-roles.js.map +1 -0
- package/src/lib/app-utils/organizations.d.ts +407 -0
- package/src/lib/app-utils/organizations.js +511 -0
- package/src/lib/app-utils/organizations.js.map +1 -0
- package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
- package/src/lib/app-utils/page-header-actions-context.js +58 -0
- package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
- package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
- package/src/lib/app-utils/page-header-record-context.js +64 -0
- package/src/lib/app-utils/page-header-record-context.js.map +1 -0
- package/src/lib/app-utils/page-markdown.d.ts +103 -0
- package/src/lib/app-utils/page-markdown.js +385 -0
- package/src/lib/app-utils/page-markdown.js.map +1 -0
- package/src/lib/app-utils/paid-media-source.d.ts +90 -0
- package/src/lib/app-utils/paid-media-source.js +184 -0
- package/src/lib/app-utils/paid-media-source.js.map +1 -0
- package/src/lib/app-utils/palette-sx.d.ts +34 -0
- package/src/lib/app-utils/palette-sx.js +150 -0
- package/src/lib/app-utils/palette-sx.js.map +1 -0
- package/src/lib/app-utils/password-policy.d.ts +47 -0
- package/src/lib/app-utils/password-policy.js +46 -0
- package/src/lib/app-utils/password-policy.js.map +1 -0
- package/src/lib/app-utils/payments-configured.d.ts +84 -0
- package/src/lib/app-utils/payments-configured.js +88 -0
- package/src/lib/app-utils/payments-configured.js.map +1 -0
- package/src/lib/app-utils/person-erasure.d.ts +126 -0
- package/src/lib/app-utils/person-erasure.js +121 -0
- package/src/lib/app-utils/person-erasure.js.map +1 -0
- package/src/lib/app-utils/person-key.d.ts +32 -0
- package/src/lib/app-utils/person-key.js +62 -0
- package/src/lib/app-utils/person-key.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
- package/src/lib/app-utils/plan-entitlements.js +4085 -0
- package/src/lib/app-utils/plan-entitlements.js.map +1 -0
- package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
- package/src/lib/app-utils/platform-ad-conversions.js +174 -0
- package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
- package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
- package/src/lib/app-utils/platform-advertising-tags.js +203 -0
- package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
- package/src/lib/app-utils/platform-brand.d.ts +151 -0
- package/src/lib/app-utils/platform-brand.js +175 -0
- package/src/lib/app-utils/platform-brand.js.map +1 -0
- package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
- package/src/lib/app-utils/platform-consent-default.js +295 -0
- package/src/lib/app-utils/platform-consent-default.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
- package/src/lib/app-utils/platform-marketing-consent.js +182 -0
- package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
- package/src/lib/app-utils/platform-marketing-host.js +97 -0
- package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
- package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
- package/src/lib/app-utils/platform-visitor-consent.js +533 -0
- package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
- package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
- package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
- package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
- package/src/lib/app-utils/plugin-artifact-path.js +33 -0
- package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
- package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
- package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
- package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
- package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
- package/src/lib/app-utils/plugin-manifest.js +687 -0
- package/src/lib/app-utils/plugin-manifest.js.map +1 -0
- package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
- package/src/lib/app-utils/published-legal-pages.js +90 -0
- package/src/lib/app-utils/published-legal-pages.js.map +1 -0
- package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
- package/src/lib/app-utils/publisher-agreement.js +274 -0
- package/src/lib/app-utils/publisher-agreement.js.map +1 -0
- package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
- package/src/lib/app-utils/publisher-attestation.js +158 -0
- package/src/lib/app-utils/publisher-attestation.js.map +1 -0
- package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
- package/src/lib/app-utils/recipient-email-render.js +221 -0
- package/src/lib/app-utils/recipient-email-render.js.map +1 -0
- package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
- package/src/lib/app-utils/redispatch-caught-error.js +46 -0
- package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
- package/src/lib/app-utils/registering-plugin.d.ts +19 -0
- package/src/lib/app-utils/registering-plugin.js +38 -0
- package/src/lib/app-utils/registering-plugin.js.map +1 -0
- package/src/lib/app-utils/release-flags.d.ts +283 -0
- package/src/lib/app-utils/release-flags.js +518 -0
- package/src/lib/app-utils/release-flags.js.map +1 -0
- package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
- package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
- package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
- package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
- package/src/lib/app-utils/repeat-infringer.js +188 -0
- package/src/lib/app-utils/repeat-infringer.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +115 -0
- package/src/lib/app-utils/repeat-sources.js +86 -0
- package/src/lib/app-utils/repeat-sources.js.map +1 -0
- package/src/lib/app-utils/request-geo.d.ts +114 -0
- package/src/lib/app-utils/request-geo.js +247 -0
- package/src/lib/app-utils/request-geo.js.map +1 -0
- package/src/lib/app-utils/request-ip.d.ts +213 -0
- package/src/lib/app-utils/request-ip.js +344 -0
- package/src/lib/app-utils/request-ip.js.map +1 -0
- package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
- package/src/lib/app-utils/resolve-named-tokens.js +59 -0
- package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
- package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
- package/src/lib/app-utils/responsive-typography-sx.js +122 -0
- package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
- package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
- package/src/lib/app-utils/reusable-component-keys.js +140 -0
- package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
- package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
- package/src/lib/app-utils/reusable-prop-values.js +494 -0
- package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
- package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
- package/src/lib/app-utils/safe-json-ld.js +37 -0
- package/src/lib/app-utils/safe-json-ld.js.map +1 -0
- package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
- package/src/lib/app-utils/sanitize-svg.js +460 -0
- package/src/lib/app-utils/sanitize-svg.js.map +1 -0
- package/src/lib/app-utils/scheme-sx.d.ts +84 -0
- package/src/lib/app-utils/scheme-sx.js +148 -0
- package/src/lib/app-utils/scheme-sx.js.map +1 -0
- package/src/lib/app-utils/scope-tokens.d.ts +249 -0
- package/src/lib/app-utils/scope-tokens.js +331 -0
- package/src/lib/app-utils/scope-tokens.js.map +1 -0
- package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
- package/src/lib/app-utils/screen-link-context-value.js +43 -0
- package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
- package/src/lib/app-utils/screen-link-context.d.ts +185 -0
- package/src/lib/app-utils/screen-link-context.js +304 -0
- package/src/lib/app-utils/screen-link-context.js.map +1 -0
- package/src/lib/app-utils/screen-link-value.d.ts +269 -0
- package/src/lib/app-utils/screen-link-value.js +384 -0
- package/src/lib/app-utils/screen-link-value.js.map +1 -0
- package/src/lib/app-utils/screen-route.d.ts +669 -0
- package/src/lib/app-utils/screen-route.js +751 -0
- package/src/lib/app-utils/screen-route.js.map +1 -0
- package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
- package/src/lib/app-utils/screen-seo-fields.js +42 -0
- package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
- package/src/lib/app-utils/search-indexing.d.ts +162 -0
- package/src/lib/app-utils/search-indexing.js +207 -0
- package/src/lib/app-utils/search-indexing.js.map +1 -0
- package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
- package/src/lib/app-utils/seo-listing-fields.js +75 -0
- package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
- package/src/lib/app-utils/seo-locale.d.ts +119 -0
- package/src/lib/app-utils/seo-locale.js +133 -0
- package/src/lib/app-utils/seo-locale.js.map +1 -0
- package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
- package/src/lib/app-utils/seo-title-variables.js +190 -0
- package/src/lib/app-utils/seo-title-variables.js.map +1 -0
- package/src/lib/app-utils/seo-title.d.ts +70 -0
- package/src/lib/app-utils/seo-title.js +117 -0
- package/src/lib/app-utils/seo-title.js.map +1 -0
- package/src/lib/app-utils/server.d.ts +174 -0
- package/src/lib/app-utils/server.js +314 -0
- package/src/lib/app-utils/server.js.map +1 -0
- package/src/lib/app-utils/site-context.d.ts +106 -0
- package/src/lib/app-utils/site-context.js +100 -0
- package/src/lib/app-utils/site-context.js.map +1 -0
- package/src/lib/app-utils/sitemap.d.ts +117 -0
- package/src/lib/app-utils/sitemap.js +183 -0
- package/src/lib/app-utils/sitemap.js.map +1 -0
- package/src/lib/app-utils/social-image.d.ts +112 -0
- package/src/lib/app-utils/social-image.js +191 -0
- package/src/lib/app-utils/social-image.js.map +1 -0
- package/src/lib/app-utils/starter-templates.d.ts +99 -0
- package/src/lib/app-utils/starter-templates.js +579 -0
- package/src/lib/app-utils/starter-templates.js.map +1 -0
- package/src/lib/app-utils/stored-nodes.d.ts +120 -0
- package/src/lib/app-utils/stored-nodes.js +174 -0
- package/src/lib/app-utils/stored-nodes.js.map +1 -0
- package/src/lib/app-utils/strip-undefined.d.ts +59 -0
- package/src/lib/app-utils/strip-undefined.js +95 -0
- package/src/lib/app-utils/strip-undefined.js.map +1 -0
- package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
- package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
- package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
- package/src/lib/app-utils/support-tiers.d.ts +108 -0
- package/src/lib/app-utils/support-tiers.js +201 -0
- package/src/lib/app-utils/support-tiers.js.map +1 -0
- package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
- package/src/lib/app-utils/timezone-geo-hint.js +180 -0
- package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
- package/src/lib/app-utils/upload-cors.d.ts +155 -0
- package/src/lib/app-utils/upload-cors.js +254 -0
- package/src/lib/app-utils/upload-cors.js.map +1 -0
- package/src/lib/app-utils/upload-inspection.d.ts +159 -0
- package/src/lib/app-utils/upload-inspection.js +539 -0
- package/src/lib/app-utils/upload-inspection.js.map +1 -0
- package/src/lib/app-utils/url-slug.d.ts +40 -0
- package/src/lib/app-utils/url-slug.js +42 -0
- package/src/lib/app-utils/url-slug.js.map +1 -0
- package/src/lib/app-utils/usage-budget.d.ts +429 -0
- package/src/lib/app-utils/usage-budget.js +421 -0
- package/src/lib/app-utils/usage-budget.js.map +1 -0
- package/src/lib/app-utils/variables.d.ts +96 -0
- package/src/lib/app-utils/variables.js +233 -0
- package/src/lib/app-utils/variables.js.map +1 -0
- package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
- package/src/lib/app-utils/video-asset-facts.js +70 -0
- package/src/lib/app-utils/video-asset-facts.js.map +1 -0
- package/src/lib/app-utils/video-object.d.ts +89 -0
- package/src/lib/app-utils/video-object.js +245 -0
- package/src/lib/app-utils/video-object.js.map +1 -0
- package/src/lib/app-utils/visitor-consent.d.ts +757 -0
- package/src/lib/app-utils/visitor-consent.js +981 -0
- package/src/lib/app-utils/visitor-consent.js.map +1 -0
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
- package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
- package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
- package/src/lib/app-utils/web-vitals-rum.js +278 -0
- package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
- package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
- package/src/lib/app-utils/webhook-delivery.js +413 -0
- package/src/lib/app-utils/webhook-delivery.js.map +1 -0
- package/src/lib/app-utils/where-used.d.ts +57 -0
- package/src/lib/app-utils/where-used.js +59 -0
- package/src/lib/app-utils/where-used.js.map +1 -0
- package/src/lib/app-utils/wistia-embed.d.ts +86 -0
- package/src/lib/app-utils/wistia-embed.js +119 -0
- package/src/lib/app-utils/wistia-embed.js.map +1 -0
- package/src/lib/app-utils/workflows.d.ts +136 -0
- package/src/lib/app-utils/workflows.js +346 -0
- package/src/lib/app-utils/workflows.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
- package/src/lib/canvas-manager/canvas-manager.js +1311 -0
- package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
- package/src/lib/canvas-manager/index.d.ts +20 -0
- package/src/lib/canvas-manager/index.js +21 -0
- package/src/lib/canvas-manager/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/index.d.ts +17 -0
- package/src/lib/canvas-manager/stores/index.js +18 -0
- package/src/lib/canvas-manager/stores/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
- package/src/lib/canvas-manager/stores/node.store.js +45 -0
- package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
- package/src/lib/components-manager/components-manager.d.ts +56 -0
- package/src/lib/components-manager/components-manager.js +191 -0
- package/src/lib/components-manager/components-manager.js.map +1 -0
- package/src/lib/components-manager/index.d.ts +18 -0
- package/src/lib/components-manager/index.js +19 -0
- package/src/lib/components-manager/index.js.map +1 -0
- package/src/lib/emit-manager/emit-manager.d.ts +56 -0
- package/src/lib/emit-manager/emit-manager.js +60 -0
- package/src/lib/emit-manager/emit-manager.js.map +1 -0
- package/src/lib/emit-manager/index.d.ts +18 -0
- package/src/lib/emit-manager/index.js +19 -0
- package/src/lib/emit-manager/index.js.map +1 -0
- package/src/lib/foundation/constants/_internal.d.ts +18 -0
- package/src/lib/foundation/constants/_internal.js +62 -0
- package/src/lib/foundation/constants/_internal.js.map +1 -0
- package/src/lib/foundation/constants/app.d.ts +23 -0
- package/src/lib/foundation/constants/app.js +25 -0
- package/src/lib/foundation/constants/app.js.map +1 -0
- package/src/lib/foundation/constants/canvas.d.ts +18 -0
- package/src/lib/foundation/constants/canvas.js +18 -0
- package/src/lib/foundation/constants/canvas.js.map +1 -0
- package/src/lib/foundation/constants/components.d.ts +54 -0
- package/src/lib/foundation/constants/components.js +61 -0
- package/src/lib/foundation/constants/components.js.map +1 -0
- package/src/lib/foundation/constants/shared.d.ts +50 -0
- package/src/lib/foundation/constants/shared.js +49 -0
- package/src/lib/foundation/constants/shared.js.map +1 -0
- package/src/lib/foundation/constants/symbol.d.ts +63 -0
- package/src/lib/foundation/constants/symbol.js +75 -0
- package/src/lib/foundation/constants/symbol.js.map +1 -0
- package/src/lib/foundation/definitions/components.types.d.ts +372 -0
- package/src/lib/foundation/definitions/components.types.js +180 -0
- package/src/lib/foundation/definitions/components.types.js.map +1 -0
- package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
- package/src/lib/foundation/definitions/contact.types.js +107 -0
- package/src/lib/foundation/definitions/contact.types.js.map +1 -0
- package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
- package/src/lib/foundation/definitions/host-content-collections.js +219 -0
- package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
- package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
- package/src/lib/foundation/definitions/org-billing.types.js +77 -0
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
- package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
- package/src/lib/foundation/definitions/organization.types.js +42 -0
- package/src/lib/foundation/definitions/organization.types.js.map +1 -0
- package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
- package/src/lib/foundation/definitions/platform.types.js +124 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -0
- package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
- package/src/lib/foundation/definitions/property-kinds.js +565 -0
- package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
- package/src/lib/foundation/definitions/shared.d.ts +23 -0
- package/src/lib/foundation/definitions/shared.js +18 -0
- package/src/lib/foundation/definitions/shared.js.map +1 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
- package/src/lib/foundation/index.d.ts +32 -0
- package/src/lib/foundation/index.js +67 -0
- package/src/lib/foundation/index.js.map +1 -0
- package/src/lib/lifecycle.d.ts +24 -0
- package/src/lib/lifecycle.js +39 -0
- package/src/lib/lifecycle.js.map +1 -0
- package/src/lib/mst/common.d.ts +17 -0
- package/src/lib/mst/common.js +23 -0
- package/src/lib/mst/common.js.map +1 -0
- package/src/lib/mst/index.d.ts +19 -0
- package/src/lib/mst/index.js +20 -0
- package/src/lib/mst/index.js.map +1 -0
- package/src/lib/mst/json.d.ts +22 -0
- package/src/lib/mst/json.js +23 -0
- package/src/lib/mst/json.js.map +1 -0
- package/src/lib/mst/types.d.ts +20 -0
- package/src/lib/mst/types.js +18 -0
- package/src/lib/mst/types.js.map +1 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
- package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
- package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
- package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
- package/src/lib/plugin-manager/custom-fields.js +39 -0
- package/src/lib/plugin-manager/custom-fields.js.map +1 -0
- package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
- package/src/lib/plugin-manager/editor-sessions.js +137 -0
- package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
- package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
- package/src/lib/plugin-manager/enabled-plugins.js +403 -0
- package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
- package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
- package/src/lib/plugin-manager/feature-plugins.js +609 -0
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
- package/src/lib/plugin-manager/index.d.ts +42 -0
- package/src/lib/plugin-manager/index.js +46 -0
- package/src/lib/plugin-manager/index.js.map +1 -0
- package/src/lib/plugin-manager/install-presets.d.ts +93 -0
- package/src/lib/plugin-manager/install-presets.js +86 -0
- package/src/lib/plugin-manager/install-presets.js.map +1 -0
- package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
- package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
- package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
- package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
- package/src/lib/plugin-manager/order-fulfilment.js +104 -0
- package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
- package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
- package/src/lib/plugin-manager/plugin-bridge.js +154 -0
- package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
- package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
- package/src/lib/plugin-manager/plugin-config.js +228 -0
- package/src/lib/plugin-manager/plugin-config.js.map +1 -0
- package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
- package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
- package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
- package/src/lib/plugin-manager/plugin-contributions.js +283 -0
- package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
- package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
- package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
- package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
- package/src/lib/plugin-manager/plugin-events.js +79 -0
- package/src/lib/plugin-manager/plugin-events.js.map +1 -0
- package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
- package/src/lib/plugin-manager/plugin-figures.js +252 -0
- package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
- package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
- package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
- package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
- package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
- package/src/lib/plugin-manager/plugin-jobs.js +182 -0
- package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
- package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
- package/src/lib/plugin-manager/plugin-loader.js +223 -0
- package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
- package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
- package/src/lib/plugin-manager/plugin-manager.js +343 -0
- package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
- package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-permissions.js +77 -0
- package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
- package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
- package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
- package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
- package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
- package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
- package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
- package/src/lib/plugin-manager/plugin-services.js +153 -0
- package/src/lib/plugin-manager/plugin-services.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
- package/src/lib/plugin-manager/plugin-styles.js +186 -0
- package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
- package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
- package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
- package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
- package/src/lib/plugin-manager/plugin-zones.js +74 -0
- package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
- package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
- package/src/lib/plugin-manager/realm-plugins.js +196 -0
- package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
- package/src/lib/plugin-manager/realm-server.d.ts +54 -0
- package/src/lib/plugin-manager/realm-server.js +88 -0
- package/src/lib/plugin-manager/realm-server.js.map +1 -0
- package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
- package/src/lib/plugin-manager/record-zone-props.js +31 -0
- package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
- package/src/lib/plugin-manager/site-page-hooks.js +114 -0
- package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
- package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
- package/src/lib/plugin-manager/site-runtime.js +25 -0
- package/src/lib/plugin-manager/site-runtime.js.map +1 -0
- package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
- package/src/lib/types/ast.d.ts +199 -0
- package/src/lib/types/ast.js +20 -0
- package/src/lib/types/ast.js.map +1 -0
- package/src/lib/types/index.d.ts +20 -0
- package/src/lib/types/index.js +21 -0
- package/src/lib/types/index.js.map +1 -0
- package/src/lib/types/nodes.d.ts +608 -0
- package/src/lib/types/nodes.js +28 -0
- package/src/lib/types/nodes.js.map +1 -0
- package/src/lib/types/routing.d.ts +17 -0
- package/src/lib/types/routing.js +18 -0
- package/src/lib/types/routing.js.map +1 -0
- package/src/lib/types/screen.d.ts +23 -0
- package/src/lib/types/screen.js +18 -0
- package/src/lib/types/screen.js.map +1 -0
- package/src/lib/utils.d.ts +25 -0
- package/src/lib/utils.js +42 -0
- package/src/lib/utils.js.map +1 -0
- package/src/server.d.ts +37 -0
- package/src/server.js +55 -0
- package/src/server.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/dynamic-list-rule.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The rule behind a dynamic list (`docs/specs/email-overhaul.md` §3b/§3c).\n *\n * A list has held manually enrolled members only. A dynamic one stores this\n * rule instead and materializes into the same `members` subcollection, so the\n * send path keeps reading one deterministic collection rather than running an\n * unbounded scan per campaign.\n *\n * ## It extends the segment vocabulary rather than inventing one\n *\n * `tags` and `captureSources` mean exactly what they mean in\n * `contactMatchesSegment`, which this module reuses rather than restating:\n * two filter languages over the same contact document would drift, and the\n * one that drifts is whichever the merchant is not looking at. What is new is\n * a SOURCE dimension, because a list must be able to draw from silos that are\n * not `contacts` at all.\n *\n * ## Every field reads a value that is already written\n *\n * Nothing here collects anything new. `tags`, `captureSources` and the\n * `behavior` figures are contact fields; `formNames` is the `formName` a\n * submission already stores; `createdAfterMs`/`createdBeforeMs` read the\n * `createdAt` all three person silos already stamp; `campaignIds` reads the\n * membership `campaign-membership.ts` defines, which the forms console writes\n * and the submit route propagates.\n *\n * ⚠️ A rule selects an AUDIENCE. It does not grant consent — a person matched\n * by \"submitted a form\" has not opted in by submitting it. Membership and\n * basis are separate joins and `marketing-consent.ts` owns the second one.\n */\n\nimport { normalizeCampaignIds } from './campaign-membership'\nimport {\n CONTACT_SOURCE_LABELS,\n contactMatchesSegment,\n type ContactSource,\n} from './contacts'\nimport {\n isContactLifecycleStage,\n normalizeContactFieldKey,\n type ContactCustomValue,\n type ContactLifecycleStage,\n CRM_CONTACT_VIEW_FIELDS,\n crmContactCustomKey,\n type CrmViewFilterClause,\n} from './crm'\n\n/** The silos a dynamic list may draw people from. */\nexport type DynamicListSource =\n | 'contacts'\n | 'leads'\n | 'siteMembers'\n /**\n * `hosts/{hostId}/formSubmissions`, which is what answers \"everyone who\n * submitted form X\" — the form's NAME is on the submission and on nothing\n * else. A contact captured by a form records only that some form produced\n * it (`sources.form`), so `captureSources` cannot express the question.\n */\n | 'formSubmissions'\n\n/**\n * The silos whose rows can be filed under a campaign.\n *\n * A contact carries the membership inside the holder's own facet and a form\n * submission carries the membership its form had when it arrived. A lead and a\n * site member carry none — nothing writes one — so the campaign dimension is\n * SKIPPED for them rather than failed, which is the same discipline every\n * silo-specific dimension here follows.\n *\n * Stated as a value because both the matcher and the materializer's enrichment\n * decide off it, and two lists would drift into a rule that selects a silo the\n * scan never reads the field for.\n */\nexport const CAMPAIGN_MEMBER_SILOS: DynamicListSource[] = [\n 'contacts',\n 'formSubmissions',\n]\n\n/** Purchase-history filters. Contacts only — no other silo stores RFM. */\nexport interface DynamicListBehavior {\n ordersCountAtLeast?: number\n ltvCentsAtLeast?: number\n lastPurchaseWithinDays?: number\n /**\n * Lapsed customers. A person who has NEVER purchased does not match: the\n * question is \"bought once and stopped\", and answering it with everybody\n * who never bought would put the whole audience in a win-back campaign.\n */\n noPurchaseForDays?: number\n}\n\n/**\n * Engagement filters, read from the per-person rollup the delivery webhook\n * maintains on `emailDeliveries/{personKey}`.\n *\n * ## Why the \"for N days\" arms count people with no record, and\n * `noPurchaseForDays` beside them does not\n *\n * A purchase is an act the person performed, so \"no purchase on file\" is\n * strong evidence they did not buy — and somebody who never bought is not a\n * LAPSED customer. An open is not like that. We learn of one only if we\n * mailed them, the message arrived, and their client loaded the tracking\n * pixel, so \"no open on file\" and \"did not open\" rest on the same evidence.\n * A merchant asking for people who are not engaging means the silent ones\n * too, and the sentences the console reads back say which lean applies rather\n * than leaving it to be inferred.\n *\n * ## Opens are the weaker signal, and the field names keep them apart\n *\n * Apple's Mail Privacy Protection prefetches images, so an open is partly a\n * statement about a mail client; a click is a statement about a person. Both\n * are offered because both are stored, and they are never merged into one\n * \"engaged\" number that would hide which of the two a rule rests on.\n */\nexport interface DynamicListEngagement {\n /** Opened any of our mail within the last N days. */\n openedWithinDays?: number\n /** Clicked a link in any of our mail within the last N days. */\n clickedWithinDays?: number\n /** No open on record for at least N days — never opened counts. */\n notOpenedForDays?: number\n /** No click on record for at least N days — never clicked counts. */\n notClickedForDays?: number\n}\n\n/**\n * How a custom-field clause compares the stored value to the one it names.\n *\n * Seven operators and no more, because each one has to be readable back as\n * a sentence and each one has to state what it does with a BLANK value —\n * see {@link customValueMatches} for the lean every operator takes.\n */\nexport const DYNAMIC_LIST_CUSTOM_OPS = [\n 'eq',\n 'neq',\n 'contains',\n 'gt',\n 'lt',\n 'set',\n 'unset',\n] as const\n\nexport type DynamicListCustomOp = (typeof DYNAMIC_LIST_CUSTOM_OPS)[number]\n\n/** The operators that compare against a value the clause carries. */\nconst VALUED_CUSTOM_OPS: ReadonlySet<DynamicListCustomOp> = new Set([\n 'eq',\n 'neq',\n 'contains',\n 'gt',\n 'lt',\n])\n\n/**\n * One condition on one custom contact field (AGL-2603).\n *\n * `key` is the {@link ContactFieldDefinition.key} the value is stored under\n * in the holder's facet, `op` says how to compare and `value` is what to\n * compare with — absent for `set` and `unset`, which ask about presence\n * rather than content. Scalars only, because that is all a custom field may\n * hold.\n */\nexport interface DynamicListCustomClause {\n key: string\n op: DynamicListCustomOp\n value?: string | number | boolean\n}\n\n/**\n * The most custom-field clauses one block may carry.\n *\n * A bound on the predicate rather than on the audience — every clause is\n * evaluated in memory against a candidate already read — kept small for the\n * reason the branch cap is: the rule is merchant-authored and a stored array\n * has no natural end.\n */\nexport const DYNAMIC_LIST_MAX_CUSTOM_CLAUSES = 20\n\n/**\n * One AND-block of filters.\n *\n * Everything except `sources` and `segmentId`, which stay on the rule itself\n * — see {@link DynamicListRule.sources} for why the source list may not move\n * into a branch and may not be negated.\n */\nexport interface DynamicListDimensions {\n /** Contacts only: at least one of these tags. */\n tags?: string[]\n /** Contacts only: captured by at least one of these surfaces. */\n captureSources?: ContactSource[]\n /** `formSubmissions` only: at least one of these form names, case-insensitive. */\n formNames?: string[]\n /**\n * {@link CAMPAIGN_MEMBER_SILOS} only: filed under at least one of these\n * campaigns, by campaign id.\n *\n * ⚠️ NOT the campaign a person's browser was attributed TO. A campaign\n * TOUCH says which ad or link brought somebody in and lives on the\n * attribution record; this says which campaign the merchant FILED the\n * record under. The two are different facts about different acts and a\n * single dimension over both would answer neither question — see\n * `campaign-attribution.ts` for the other one.\n *\n * ⛔ And membership is not consent. A person selected by this dimension has\n * opted in to nothing: they are here because a merchant put a form in a\n * campaign, which is the merchant's own act. The materializer enrolls with\n * no basis at all, and this dimension does not change that.\n */\n campaignIds?: string[]\n /** Any silo: the record was created at or after this instant. */\n createdAfterMs?: number\n /** Any silo: the record was created strictly before this instant. */\n createdBeforeMs?: number\n /** Contacts only. */\n behavior?: DynamicListBehavior\n /** Any silo — engagement is a fact about an address, not about a silo row. */\n engagement?: DynamicListEngagement\n /** Already a member of every one of these lists. */\n inListIds?: string[]\n /** A member of none of these lists — the \"not in list X\" every rival has. */\n notInListIds?: string[]\n /*\n * THE CRM DIMENSIONS (AGL-2603) — contacts only, every one of them.\n *\n * All four read the holder's FACET on the shared contact row, beside the\n * tags: an owner, a lifecycle stage, a company and a custom field are one\n * business's knowledge of a person, and the materializer reads them under\n * the sweeping site's own group so that no rule can select another\n * holder's segmentation. A lead, a site member and a form submission carry\n * none of them, so the dimensions are SKIPPED for those silos rather than\n * failed — the same discipline `tags` follows, and the same caveat about a\n * negated branch whose only filter is one of these.\n *\n * A contact with no value on the field does not match any of the first\n * three: \"owned by A\" is not satisfied by nobody owning them. The custom\n * operators each state their own lean — see {@link customValueMatches}.\n */\n /** Owned by any of these team members, by account uid. */\n ownerUids?: string[]\n /** In any of these lifecycle stages. */\n lifecycleStages?: ContactLifecycleStage[]\n /** At any of these companies, by `orgs/{orgId}/companies` id. */\n companyIds?: string[]\n /** Every clause must hold — AND within the dimension, unlike the lists above. */\n custom?: DynamicListCustomClause[]\n /**\n * Opened or clicked a campaign sent by the sweeping holder's sites within\n * the last N days (AGL-2616) — the re-engagement audience.\n *\n * Read from the holder's facet like the four above, and contacts only for\n * the same reason. It is NOT the {@link engagement} block one field up:\n * that reads the address-level rollup, which counts every sender's mail\n * to the address — a receipt, an invite, a sibling business's newsletter —\n * and a \"win back our quiet readers\" audience built on it would mail\n * people who are reading somebody else. This reads what the delivery\n * webhook stamped on OUR facet from OUR campaigns. A contact with no stamp\n * does not match, the dated-window lean the CRM dimensions all take.\n */\n engagedWithinDays?: number\n}\n\n/** One OR branch: an AND-block that may be inverted. */\nexport interface DynamicListRuleGroup extends DynamicListDimensions {\n /**\n * Invert this branch.\n *\n * ⚠️ A branch whose dimensions do not apply to a candidate's silo matches\n * VACUOUSLY — this rule language skips inapplicable dimensions rather than\n * failing them — so negating such a branch excludes that silo entirely.\n * That is the honest consequence of the skip rule rather than a special\n * case bolted onto it, and every clause the console reads back names the\n * silo its dimension applies to.\n */\n negate?: boolean\n}\n\n/** The stored `rule` on a `kind: 'dynamic'` list document. */\nexport interface DynamicListRule extends DynamicListDimensions {\n /**\n * Which silos to draw from. Empty is not \"all\" — it matches nobody.\n *\n * ⛔ NOT groupable and NOT negatable, and that is a materializer constraint\n * rather than a modelling preference. `sources` is the SCAN PLAN: it\n * decides which collections are paged and in what order, and it is what the\n * resume cursor names when a sweep runs out of budget. A negated source\n * would mean \"every silo except\", which is a scan of collections the rule\n * does not name; a source inside an OR branch would mean two scan plans for\n * one rule. Either breaks the budget, the cursor, or both.\n */\n sources: DynamicListSource[]\n /** Reuse a saved contact segment's tags and sources. Contacts only. */\n segmentId?: string\n /**\n * Reuse a saved contacts VIEW's filters (AGL-2617). Contacts only.\n *\n * `orgs/{orgId}/crmViews/{viewId}`, a view over the Contacts section.\n * Resolved once by the materializer into the dimensions this rule\n * language already has — see {@link dynamicListDimensionsForCrmView} —\n * and applied to the rule's top-level block the way a segment is: it\n * always applies, and it is not folded into the OR branches. A view whose\n * filters this language cannot express narrows to nobody, which is the\n * same lean a deleted segment takes: a rule must not quietly select more\n * than the view it reads as.\n */\n viewId?: string\n /**\n * Invert the rule's own top-level block — \"people who do NOT match these\".\n *\n * Applies to the dimensions on this object and to the resolved segment. It\n * does not touch `sources`, and it does not touch {@link any}, which is\n * ANDed with it and carries its own per-branch negation.\n */\n negate?: boolean\n /**\n * OR branches. A candidate must match at least one of them.\n *\n * ANDed with the top-level block, so a rule can say \"drawn from contacts,\n * tagged vip, AND (spent over $500 OR ordered at least three times)\" — the\n * shape a flat AND list cannot express and every compared product has.\n * Absent or empty is no constraint at all, rather than a constraint nothing\n * satisfies.\n */\n any?: DynamicListRuleGroup[]\n}\n\n/** One person as the materializer reads them out of a silo. */\nexport interface DynamicListCandidate {\n silo: DynamicListSource\n email: string\n name?: string\n createdAtMs?: number | null\n /** Contacts only. */\n tags?: string[]\n /** Contacts only — the `sources` map, not the rule's `captureSources`. */\n sources?: Partial<Record<ContactSource, true>>\n ordersCount?: number\n ltvCents?: number\n lastPurchaseAtMs?: number | null\n /** `formSubmissions` only. */\n formName?: string\n /**\n * {@link CAMPAIGN_MEMBER_SILOS} only — the campaigns this row is filed\n * under.\n *\n * Read from a different place in each of the two silos and normalized to one\n * shape by the scan: a submission carries the field at the top of its\n * document, a contact carries it inside the reading holder's facet, because\n * a contact row is shared by every site in the org.\n */\n campaignIds?: string[]\n /*\n * ENRICHMENT — filled by a keyed lookup, not by the silo document.\n *\n * The two below describe an ADDRESS rather than a row, so they cannot come\n * out of the scan the way everything above does. The materializer fetches\n * them a page at a time, by document key, and only for a rule that asks —\n * see `dynamicListRuleNeedsEngagement` and `dynamicListRuleNeedsLists`.\n * Absent means \"not looked up\"; the matcher reads absent as no record,\n * which is the reading each dimension's own documentation states.\n */\n lastOpenedAtMs?: number | null\n lastClickedAtMs?: number | null\n /** Lists this person is already a member of, by list id. */\n listIds?: string[]\n /*\n * THE CRM FIELDS (AGL-2603) — contacts only, read out of the sweeping\n * holder's facet the way `campaignIds` is. Absent means the facet holds no\n * value, which the matcher reads as \"does not match\" for the first three\n * and as \"unset\" for a custom clause.\n */\n ownerUid?: string\n lifecycleStage?: ContactLifecycleStage\n companyId?: string\n /** The holder's custom values, keyed by field key. */\n custom?: Record<string, ContactCustomValue>\n /**\n * When the person last opened or clicked one of the holder's campaigns —\n * the facet stamp, read the way the fields above are. Absent when the\n * facet carries none, which the matcher reads as \"does not match\".\n */\n lastEmailEngagementAtMs?: number | null\n}\n\n/** A saved segment's filters, resolved by the caller from `segmentId`. */\nexport interface ResolvedSegmentFilters {\n tags?: string[]\n sources?: ContactSource[]\n}\n\nconst asStringArray = (value: unknown): string[] =>\n Array.isArray(value)\n ? value\n .map((entry) => String(entry ?? '').trim())\n .filter((entry) => entry.length > 0 && entry.length <= 120)\n .slice(0, 50)\n : []\n\nconst asPositiveNumber = (value: unknown): number | undefined => {\n const parsed = Number(value)\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined\n}\n\nconst DYNAMIC_LIST_SOURCES: DynamicListSource[] = [\n 'contacts',\n 'leads',\n 'siteMembers',\n 'formSubmissions',\n]\n\n/**\n * Coerces a stored rule to the shape the matcher expects.\n *\n * The rule is merchant-authored through the console and read back on a\n * scheduled sweep, so it arrives as whatever Firestore held. Unknown source\n * names are dropped rather than tolerated: a typo that fell through would\n * read as a silo the materializer never scans, and the list would quietly\n * materialize a smaller set than the rule appears to describe.\n */\n/**\n * The most OR branches one rule may carry.\n *\n * A bound on the PREDICATE, not on the audience — every branch is evaluated\n * in memory against a candidate the sweep has already read, so this costs no\n * Firestore work. It exists because the rule is merchant-authored and a\n * stored array has no natural end: a thousand branches would be a thousand\n * evaluations per candidate per sweep.\n *\n * ⚠️ Set ABOVE what the console form can produce, and that is a correctness\n * requirement rather than headroom. The form's \"any of these filters\" mode\n * puts each control in a branch of its own, so a reader who fills in every\n * box authors nineteen, plus one branch per custom-field condition up to\n * {@link DYNAMIC_LIST_MAX_CUSTOM_CLAUSES} — and dropping a branch NARROWS an\n * OR, so a cap the form could reach would silently select fewer people than\n * the sentences above the controls say. The rule editor's spec holds the sum\n * under this number.\n */\nexport const DYNAMIC_LIST_MAX_GROUPS = 40\n\n/**\n * The most lists one dimension may name.\n *\n * This one DOES cost reads — a named list is a keyed lookup per candidate per\n * page — so it is deliberately small, and it is the same number on both arms\n * so that \"in these\" and \"not in those\" cannot be combined into a larger\n * fan-out than either alone.\n */\nexport const DYNAMIC_LIST_MAX_LIST_REFERENCES = 5\n\n/**\n * Coerces a stored custom-field clause, or drops it.\n *\n * Dropped rather than tolerated for the reason a typo'd silo is: a clause\n * with a key no definition uses, an operator the matcher does not know, or a\n * missing value where one is compared against, is a filter no contact can\n * satisfy — and a rule that quietly matches nobody reads exactly like a rule\n * that has not run yet. The key goes through the definition's own normalizer\n * so a clause written against a label (`Plan Name`) still reaches the stored\n * key (`plan_name`), and a value is kept only as a scalar because that is all\n * a custom field may hold.\n */\nfunction normalizeCustomClause(raw: unknown): DynamicListCustomClause | null {\n const entry = (raw ?? {}) as Record<string, unknown>\n const key = normalizeContactFieldKey(entry['key'])\n const op = entry['op']\n if (\n !key ||\n typeof op !== 'string' ||\n !(DYNAMIC_LIST_CUSTOM_OPS as readonly string[]).includes(op)\n ) {\n return null\n }\n const operator = op as DynamicListCustomOp\n if (!VALUED_CUSTOM_OPS.has(operator)) return { key, op: operator }\n const value = entry['value']\n if (typeof value === 'string') {\n const trimmed = value.trim().slice(0, 500)\n return trimmed ? { key, op: operator, value: trimmed } : null\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? { key, op: operator, value } : null\n }\n if (typeof value === 'boolean') return { key, op: operator, value }\n return null\n}\n\n/** Coerces the dimensions shared by the rule and each of its OR branches. */\nfunction normalizeDimensions(value: Record<string, unknown>): DynamicListDimensions {\n const behavior = (value['behavior'] ?? {}) as Record<string, unknown>\n const normalizedBehavior: DynamicListBehavior = {\n ...(asPositiveNumber(behavior['ordersCountAtLeast']) !== undefined\n ? { ordersCountAtLeast: asPositiveNumber(behavior['ordersCountAtLeast']) }\n : {}),\n ...(asPositiveNumber(behavior['ltvCentsAtLeast']) !== undefined\n ? { ltvCentsAtLeast: asPositiveNumber(behavior['ltvCentsAtLeast']) }\n : {}),\n ...(asPositiveNumber(behavior['lastPurchaseWithinDays']) !== undefined\n ? {\n lastPurchaseWithinDays: asPositiveNumber(\n behavior['lastPurchaseWithinDays'],\n ),\n }\n : {}),\n ...(asPositiveNumber(behavior['noPurchaseForDays']) !== undefined\n ? { noPurchaseForDays: asPositiveNumber(behavior['noPurchaseForDays']) }\n : {}),\n }\n const engagement = (value['engagement'] ?? {}) as Record<string, unknown>\n const normalizedEngagement: DynamicListEngagement = {\n ...(asPositiveNumber(engagement['openedWithinDays']) !== undefined\n ? { openedWithinDays: asPositiveNumber(engagement['openedWithinDays']) }\n : {}),\n ...(asPositiveNumber(engagement['clickedWithinDays']) !== undefined\n ? { clickedWithinDays: asPositiveNumber(engagement['clickedWithinDays']) }\n : {}),\n ...(asPositiveNumber(engagement['notOpenedForDays']) !== undefined\n ? { notOpenedForDays: asPositiveNumber(engagement['notOpenedForDays']) }\n : {}),\n ...(asPositiveNumber(engagement['notClickedForDays']) !== undefined\n ? { notClickedForDays: asPositiveNumber(engagement['notClickedForDays']) }\n : {}),\n }\n const tags = asStringArray(value['tags'])\n const captureSources = asStringArray(value['captureSources']) as ContactSource[]\n const formNames = asStringArray(value['formNames'])\n // Through the campaign field's own normalizer rather than the local string\n // coercion: the cap, the dedupe and the trim are properties of the stored\n // membership, and a second reading of them here would let a rule name more\n // campaigns than any record is allowed to be filed under.\n const campaignIds = normalizeCampaignIds(value['campaignIds'])\n const createdAfterMs = asPositiveNumber(value['createdAfterMs'])\n const createdBeforeMs = asPositiveNumber(value['createdBeforeMs'])\n const inListIds = asStringArray(value['inListIds']).slice(\n 0,\n DYNAMIC_LIST_MAX_LIST_REFERENCES,\n )\n const notInListIds = asStringArray(value['notInListIds']).slice(\n 0,\n DYNAMIC_LIST_MAX_LIST_REFERENCES,\n )\n const ownerUids = asStringArray(value['ownerUids'])\n // A stage the model does not name is dropped, not kept: kept, it would be\n // a filter no contact can satisfy, and the rule would read as the stages\n // it does name while selecting nobody.\n const lifecycleStages = asStringArray(value['lifecycleStages']).filter(\n isContactLifecycleStage,\n )\n const companyIds = asStringArray(value['companyIds'])\n const custom = (Array.isArray(value['custom']) ? value['custom'] : [])\n .slice(0, DYNAMIC_LIST_MAX_CUSTOM_CLAUSES)\n .map(normalizeCustomClause)\n .filter((clause): clause is DynamicListCustomClause => clause !== null)\n const engagedWithinDays = asPositiveNumber(value['engagedWithinDays'])\n return {\n ...(tags.length ? { tags } : {}),\n ...(captureSources.length ? { captureSources } : {}),\n ...(formNames.length ? { formNames } : {}),\n ...(campaignIds.length ? { campaignIds } : {}),\n ...(createdAfterMs !== undefined ? { createdAfterMs } : {}),\n ...(createdBeforeMs !== undefined ? { createdBeforeMs } : {}),\n ...(Object.keys(normalizedBehavior).length\n ? { behavior: normalizedBehavior }\n : {}),\n ...(Object.keys(normalizedEngagement).length\n ? { engagement: normalizedEngagement }\n : {}),\n ...(inListIds.length ? { inListIds } : {}),\n ...(notInListIds.length ? { notInListIds } : {}),\n ...(ownerUids.length ? { ownerUids } : {}),\n ...(lifecycleStages.length ? { lifecycleStages } : {}),\n ...(companyIds.length ? { companyIds } : {}),\n ...(custom.length ? { custom } : {}),\n ...(engagedWithinDays !== undefined ? { engagedWithinDays } : {}),\n }\n}\n\n/** True when a branch constrains nothing, so keeping it would widen the rule. */\nfunction dimensionsAreEmpty(dimensions: DynamicListDimensions): boolean {\n return Object.keys(dimensions).length === 0\n}\n\nexport function normalizeDynamicListRule(stored: unknown): DynamicListRule {\n const value = (stored ?? {}) as Record<string, unknown>\n const sources = asStringArray(value['sources']).filter((source): source is DynamicListSource =>\n (DYNAMIC_LIST_SOURCES as string[]).includes(source),\n )\n const segmentId = String(value['segmentId'] ?? '').trim()\n const viewId = String(value['viewId'] ?? '').trim()\n /*\n * An empty OR branch is DROPPED rather than kept.\n *\n * A branch with no dimensions matches everybody, and `any` is satisfied by\n * one branch — so a single empty one would silently disable every other\n * branch beside it. Dropping it is the same decision the source filter\n * makes about a typo'd silo name, for the same reason: a rule must not\n * quietly select a different population than the one it reads as.\n */\n const groups = (Array.isArray(value['any']) ? value['any'] : [])\n .slice(0, DYNAMIC_LIST_MAX_GROUPS)\n .map((raw) => {\n const entry = (raw ?? {}) as Record<string, unknown>\n const dimensions = normalizeDimensions(entry)\n return {\n ...dimensions,\n ...(entry['negate'] === true ? { negate: true } : {}),\n } as DynamicListRuleGroup\n })\n .filter((group) => !dimensionsAreEmpty(stripNegate(group)))\n return {\n sources,\n ...(segmentId ? { segmentId } : {}),\n ...(viewId ? { viewId } : {}),\n ...(value['negate'] === true ? { negate: true } : {}),\n ...normalizeDimensions(value),\n ...(groups.length ? { any: groups } : {}),\n }\n}\n\n/** A branch without its flag, so emptiness is decided on its filters alone. */\nfunction stripNegate(group: DynamicListRuleGroup): DynamicListDimensions {\n const { negate, ...dimensions } = group\n void negate\n return dimensions\n}\n\n/**\n * True when a rule can select nobody no matter what the data holds.\n *\n * Worth its own answer because the failure it prevents is silent: an empty\n * `sources` materializes an empty list, and an empty list reads in the\n * composer exactly like a rule that simply has not run yet.\n */\nexport function dynamicListRuleIsEmpty(rule: DynamicListRule): boolean {\n return rule.sources.length === 0\n}\n\n/**\n * Does this person match the rule?\n *\n * AND across dimensions, OR within one — the same shape `contactMatchesSegment`\n * uses, so a merchant who has built a segment already knows how this reads.\n *\n * On top of that flat block sit two operators, and the whole verdict is:\n *\n * ```\n * silo is in sources\n * AND (negate ? NOT top-level block : top-level block)\n * AND (any branches ? at least one branch, each with its own negate : true)\n * ```\n *\n * Which is nested AND/OR with negation, arranged so that the only part the\n * materializer's scan plan depends on — `sources` — sits outside both\n * operators and cannot be touched by either.\n *\n * Dimensions that do not apply to a candidate's silo are SKIPPED rather than\n * failed. A rule of `sources: ['contacts','siteMembers'], tags: ['vip']` means\n * \"VIP contacts, and site members\" — reading `tags` against a member document\n * that cannot carry tags would make the second source contribute nobody, and\n * a source that silently contributes nobody is the same defect as a dropped\n * typo above.\n *\n * @param segment filters resolved from `rule.segmentId`, when it names one.\n * @param view the dimensions resolved from `rule.viewId`, when it names\n * one — see {@link dynamicListDimensionsForCrmView}.\n * @param nowMs evaluation instant, injected so a sweep is reproducible.\n */\nexport function candidateMatchesDynamicListRule(\n candidate: DynamicListCandidate,\n rule: DynamicListRule,\n options: {\n segment?: ResolvedSegmentFilters | null\n view?: DynamicListDimensions | null\n nowMs: number\n },\n): boolean {\n /*\n * The source filter, first and outside everything else. It is the one\n * dimension that is neither negatable nor groupable, because it is the scan\n * plan rather than a filter over what the scan found.\n */\n if (!rule.sources.includes(candidate.silo)) return false\n\n /*\n * A resolved VIEW is its own AND-block beside the rule's, inside the\n * negatable top level with the segment — the view always applies, and a\n * rule that inverts its block inverts the view with it, which is what\n * \"nobody matching all of these\" reads as when a view is one of them.\n * Beside rather than merged INTO the rule's dimensions: the lists within\n * a dimension are OR, so merging a view's owners with the rule's would\n * widen both.\n */\n const top =\n matchesDimensions(candidate, rule, {\n segment: options.segment ?? null,\n nowMs: options.nowMs,\n }) &&\n (!options.view ||\n matchesDimensions(candidate, options.view, {\n segment: null,\n nowMs: options.nowMs,\n }))\n if ((rule.negate === true ? !top : top) === false) return false\n\n /*\n * The OR branches, ANDed with the block above. Absent or empty is no\n * constraint — `Array.prototype.some` on an empty array is `false`, which\n * would turn a rule that named no branches into one nobody satisfies.\n */\n const groups = rule.any ?? []\n if (!groups.length) return true\n return groups.some((group) => {\n const matched = matchesDimensions(candidate, group, {\n // A saved segment belongs to the rule, not to a branch: it is resolved\n // once by the caller from the rule's own `segmentId`, and folding it\n // into every branch would make each branch narrower than it reads.\n segment: null,\n nowMs: options.nowMs,\n })\n return group.negate === true ? !matched : matched\n })\n}\n\n/**\n * One AND-block of dimensions against one candidate.\n *\n * Extracted so the top-level block and every OR branch are decided by the\n * same code. Two implementations of \"does this person match these filters\"\n * would drift, and the half that drifts is whichever the merchant is not\n * looking at — the same reason `contactMatchesSegment` is reused here rather\n * than restated.\n */\nfunction matchesDimensions(\n candidate: DynamicListCandidate,\n rule: DynamicListDimensions,\n options: { segment: ResolvedSegmentFilters | null; nowMs: number },\n): boolean {\n const day = 86_400_000\n\n if (rule.createdAfterMs !== undefined) {\n // A record with no creation stamp cannot satisfy an age window, and\n // admitting it would put people INTO an audience the merchant bounded on\n // purpose. This is the opposite lean from the consent module's unknown\n // handling, and deliberately so: there, the unknown keeps somebody\n // reachable; here, it would add somebody the rule excluded.\n if (candidate.createdAtMs == null) return false\n if (candidate.createdAtMs < rule.createdAfterMs) return false\n }\n if (rule.createdBeforeMs !== undefined) {\n if (candidate.createdAtMs == null) return false\n if (candidate.createdAtMs >= rule.createdBeforeMs) return false\n }\n\n if (candidate.silo === 'formSubmissions' && rule.formNames?.length) {\n const wanted = new Set(rule.formNames.map((name) => name.toLowerCase()))\n if (!wanted.has(String(candidate.formName ?? '').trim().toLowerCase())) {\n return false\n }\n }\n\n /*\n * FILED UNDER A CAMPAIGN — the two silos that can be, and only those.\n *\n * OR within the dimension, like every other list here: a merchant naming\n * three campaigns means anyone in any of them, not the handful of people\n * filed under all three at once.\n *\n * A row in a silo that carries no membership is SKIPPED rather than failed,\n * so \"people in the spring push, and every site member\" contributes members\n * — the same reading `tags` gets for a lead. ⚠️ Which also means a NEGATED\n * branch whose only filter is this one excludes those silos entirely; that\n * is the honest consequence of the skip rule, stated on the branch flag\n * itself.\n */\n if (\n rule.campaignIds?.length &&\n CAMPAIGN_MEMBER_SILOS.includes(candidate.silo)\n ) {\n // An absent field reads as \"filed under nothing\", which is what a row\n // written before the form named a campaign actually says.\n const filed = new Set(candidate.campaignIds ?? [])\n if (!rule.campaignIds.some((campaignId) => filed.has(campaignId))) {\n return false\n }\n }\n\n if (candidate.silo === 'contacts') {\n const segmentFilters = {\n tags: [...(options.segment?.tags ?? []), ...(rule.tags ?? [])],\n sources: [\n ...(options.segment?.sources ?? []),\n ...(rule.captureSources ?? []),\n ],\n }\n if (\n !contactMatchesSegment(\n { tags: candidate.tags ?? [], sources: candidate.sources ?? {} },\n segmentFilters,\n )\n ) {\n return false\n }\n const behavior = rule.behavior\n if (behavior) {\n if (\n behavior.ordersCountAtLeast !== undefined &&\n (candidate.ordersCount ?? 0) < behavior.ordersCountAtLeast\n ) {\n return false\n }\n if (\n behavior.ltvCentsAtLeast !== undefined &&\n (candidate.ltvCents ?? 0) < behavior.ltvCentsAtLeast\n ) {\n return false\n }\n if (behavior.lastPurchaseWithinDays !== undefined) {\n const last = candidate.lastPurchaseAtMs ?? null\n if (last === null) return false\n if (last < options.nowMs - behavior.lastPurchaseWithinDays * day) {\n return false\n }\n }\n if (behavior.noPurchaseForDays !== undefined) {\n const last = candidate.lastPurchaseAtMs ?? null\n // Never purchased is not lapsed — see DynamicListBehavior.\n if (last === null) return false\n if (last > options.nowMs - behavior.noPurchaseForDays * day) {\n return false\n }\n }\n }\n /*\n * THE CRM DIMENSIONS — OR within each, AND across them, like the tags.\n *\n * An absent value matches none of the first three. \"Owned by A or B\" is\n * a positive claim about the relationship, and a contact nobody owns is\n * not a contact A owns; the same for a stage never set and a company\n * never linked. The lean is the dated-window one rather than the\n * consent module's: admitting the unknown here would put people INTO an\n * audience the merchant bounded on purpose.\n */\n if (rule.ownerUids?.length) {\n if (!candidate.ownerUid || !rule.ownerUids.includes(candidate.ownerUid)) {\n return false\n }\n }\n if (rule.lifecycleStages?.length) {\n if (\n !candidate.lifecycleStage ||\n !rule.lifecycleStages.includes(candidate.lifecycleStage)\n ) {\n return false\n }\n }\n if (rule.companyIds?.length) {\n if (!candidate.companyId || !rule.companyIds.includes(candidate.companyId)) {\n return false\n }\n }\n // Every clause must hold. A merchant adding a second condition on a\n // custom field is narrowing, which is what a second box on a form means\n // everywhere else in it — the OR is the `any` branches, not this list.\n for (const clause of rule.custom ?? []) {\n if (!customValueMatches(candidate.custom?.[clause.key], clause)) {\n return false\n }\n }\n /*\n * ENGAGED WITH OUR CAMPAIGNS — the facet stamp, on the same lean as\n * `lastPurchaseWithinDays`: no stamp is no match. This is the one\n * engagement figure that is about THIS holder's mail; the address-level\n * arms further down are about the address.\n */\n if (rule.engagedWithinDays !== undefined) {\n const last = candidate.lastEmailEngagementAtMs ?? null\n if (last === null) return false\n if (last < options.nowMs - rule.engagedWithinDays * day) return false\n }\n }\n\n /*\n * ENGAGEMENT — every silo, not contacts only.\n *\n * The rollup keys on the ADDRESS, and a lead, a site member and a form\n * submission all have one. Restricting this to contacts the way `behavior`\n * is restricted would be restricting it to the silo that happens to store\n * the OTHER figures, which is not a fact about engagement.\n */\n const engagement = rule.engagement\n if (engagement) {\n const opened = candidate.lastOpenedAtMs ?? null\n const clicked = candidate.lastClickedAtMs ?? null\n if (engagement.openedWithinDays !== undefined) {\n if (opened === null) return false\n if (opened < options.nowMs - engagement.openedWithinDays * day) {\n return false\n }\n }\n if (engagement.clickedWithinDays !== undefined) {\n if (clicked === null) return false\n if (clicked < options.nowMs - engagement.clickedWithinDays * day) {\n return false\n }\n }\n // No record MATCHES the quiet arms — see DynamicListEngagement for why\n // this leans the opposite way from `noPurchaseForDays` above it.\n if (engagement.notOpenedForDays !== undefined && opened !== null) {\n if (opened > options.nowMs - engagement.notOpenedForDays * day) {\n return false\n }\n }\n if (engagement.notClickedForDays !== undefined && clicked !== null) {\n if (clicked > options.nowMs - engagement.notClickedForDays * day) {\n return false\n }\n }\n }\n\n /*\n * LIST MEMBERSHIP — \"and not the people already on my customers list\".\n *\n * An absent `listIds` reads as \"on no list\", and that is the reading a\n * failed or skipped lookup gets too. The direction is chosen rather than\n * defaulted: an unenriched candidate failing `inListIds` keeps them OUT of\n * an audience, where an unenriched candidate passing `notInListIds` would\n * let a lookup failure quietly re-admit the people a merchant excluded. The\n * materializer runs the enrichment whenever a rule names a list, so the\n * absent case is a lookup that failed rather than an ordinary one — and\n * these two readings are what it costs when one does.\n */\n const memberOf = new Set(candidate.listIds ?? [])\n if (rule.inListIds?.length) {\n if (!rule.inListIds.every((listId) => memberOf.has(listId))) return false\n }\n if (rule.notInListIds?.length) {\n if (rule.notInListIds.some((listId) => memberOf.has(listId))) return false\n }\n\n return true\n}\n\n/** A value that is on the record: not absent, not `null`, not blank text. */\nconst customValueIsSet = (value: ContactCustomValue | undefined): boolean =>\n value !== undefined &&\n value !== null &&\n !(typeof value === 'string' && value.trim() === '')\n\n/** A value as text, for the comparisons that read it that way. */\nconst customValueText = (value: string | number | boolean): string =>\n String(value).trim().toLowerCase()\n\n/**\n * Does one stored custom value satisfy one clause?\n *\n * Exported because the comparison is the whole meaning of the dimension and\n * a surface that previews a value against a clause must not carry a second\n * copy of it. The leans, per operator, because each has to be readable back\n * as a sentence the merchant can check against their intent:\n *\n * - `eq` — the same value. Text compares case-insensitively and trimmed,\n * because a `select` option typed as `Enterprise` and stored as\n * `enterprise` is one option; a number and a boolean compare as\n * themselves, and a number stored as text still equals the number.\n * - `neq` — a value that is set AND differs. A blank does NOT count: a\n * merchant excluding one plan is not asking for everyone whose plan was\n * never recorded, and `unset` exists for that question.\n * - `contains` — text containment, case-insensitive; a blank contains\n * nothing.\n * - `gt` / `lt` — numeric when both sides parse as numbers, text otherwise.\n * Text ordering is what a `date` field stores (ISO dates order as text),\n * and a blank is neither greater nor less than anything.\n * - `set` / `unset` — presence. `false` and `0` are set; `null`, absent and\n * blank text are not.\n */\nexport function customValueMatches(\n value: ContactCustomValue | undefined,\n clause: DynamicListCustomClause,\n): boolean {\n const present = customValueIsSet(value)\n switch (clause.op) {\n case 'set':\n return present\n case 'unset':\n return !present\n default:\n break\n }\n if (!present || clause.value === undefined) return false\n const stored = value as string | number | boolean\n const wanted = clause.value\n switch (clause.op) {\n case 'eq':\n return customValueText(stored) === customValueText(wanted)\n case 'neq':\n return customValueText(stored) !== customValueText(wanted)\n case 'contains':\n return customValueText(stored).includes(customValueText(wanted))\n case 'gt':\n case 'lt': {\n const left = Number(stored)\n const right = Number(wanted)\n const numeric =\n typeof stored !== 'boolean' &&\n typeof wanted !== 'boolean' &&\n String(stored).trim() !== '' &&\n String(wanted).trim() !== '' &&\n Number.isFinite(left) &&\n Number.isFinite(right)\n if (numeric) return clause.op === 'gt' ? left > right : left < right\n const a = customValueText(stored)\n const b = customValueText(wanted)\n return clause.op === 'gt' ? a > b : a < b\n }\n default:\n return false\n }\n}\n\n/** Every dimension block a rule carries: its own, then each OR branch. */\nfunction allDimensions(rule: DynamicListRule): DynamicListDimensions[] {\n return [rule, ...(rule.any ?? [])]\n}\n\n/**\n * Does evaluating this rule need the sweeping holder's contact FACET?\n *\n * The campaign membership and the four CRM fields all live inside the facet,\n * which is keyed by the consent group the materializer has to resolve with\n * one org read. A rule that names none of them pays nothing — the same\n * opt-in cost `dynamicListRuleNeedsCampaigns` already describes, widened to\n * every dimension the facet holds so the materializer asks one question\n * rather than five.\n */\nexport function dynamicListRuleNeedsContactFacet(rule: DynamicListRule): boolean {\n return allDimensions(rule).some(\n (dimensions) =>\n (dimensions.campaignIds?.length ?? 0) > 0 ||\n (dimensions.ownerUids?.length ?? 0) > 0 ||\n (dimensions.lifecycleStages?.length ?? 0) > 0 ||\n (dimensions.companyIds?.length ?? 0) > 0 ||\n (dimensions.custom?.length ?? 0) > 0 ||\n dimensions.engagedWithinDays !== undefined,\n )\n}\n\n/**\n * Does evaluating this rule need the per-person engagement rollup?\n *\n * Asked by the materializer before it spends a keyed read per candidate. A\n * rule with no engagement clause anywhere pays nothing, which is what keeps\n * the lookup an opt-in cost rather than a tax on every sweep.\n */\nexport function dynamicListRuleNeedsEngagement(rule: DynamicListRule): boolean {\n return allDimensions(rule).some(\n (dimensions) =>\n dimensions.engagement !== undefined &&\n Object.keys(dimensions.engagement).length > 0,\n )\n}\n\n/**\n * Does evaluating this rule need a contact's campaign membership?\n *\n * Asked by the materializer before it resolves the consent group the facet is\n * keyed by — one org read, and only for a rule that names a campaign. A\n * submission's membership is on the row the sweep already paged and costs\n * nothing either way, so this answers about the CONTACTS silo's extra work.\n */\nexport function dynamicListRuleNeedsCampaigns(rule: DynamicListRule): boolean {\n return allDimensions(rule).some(\n (dimensions) => (dimensions.campaignIds?.length ?? 0) > 0,\n )\n}\n\n/**\n * The rule with one list id removed from both membership arms.\n *\n * ⛔ A dynamic list whose rule referred to ITSELF would oscillate, and the\n * oscillation removes people. `notInListIds: [self]` matches everybody on the\n * first sweep, which enrolls them; on the second sweep they are all members,\n * so nobody matches, and reconciliation deletes every row the rule created.\n * The third sweep enrolls them again. Membership would flip on every beat of\n * the materializing sweep forever, and half of those beats are deletions.\n *\n * A self-reference also cannot mean anything useful — the answer depends on\n * whether the sweep has run yet — so it is dropped rather than refused: a\n * merchant who picks their own audience gets the rule without that clause,\n * which is what it would have meant if it meant anything.\n */\nexport function dynamicListRuleWithoutListReference(\n rule: DynamicListRule,\n listId: string,\n): DynamicListRule {\n if (!listId) return rule\n const strip = <T extends DynamicListDimensions>(dimensions: T): T => {\n const inListIds = (dimensions.inListIds ?? []).filter((id) => id !== listId)\n const notInListIds = (dimensions.notInListIds ?? []).filter(\n (id) => id !== listId,\n )\n const next = { ...dimensions }\n if (dimensions.inListIds) {\n if (inListIds.length) next.inListIds = inListIds\n else delete next.inListIds\n }\n if (dimensions.notInListIds) {\n if (notInListIds.length) next.notInListIds = notInListIds\n else delete next.notInListIds\n }\n return next\n }\n const stripped = strip(rule)\n /*\n * A branch whose ONLY filter was the self-reference is dropped, not kept\n * empty: an empty branch matches everybody, and one satisfied branch\n * satisfies `any`, so keeping it would silently disable every branch\n * beside it. Same reasoning as the normalizer's own empty-branch drop.\n */\n const groups = (rule.any ?? [])\n .map((group) => strip(group))\n .filter((group) => Object.keys(stripNegate(group)).length > 0)\n if (groups.length) stripped.any = groups\n else delete stripped.any\n return stripped\n}\n\n/** Every list id this rule refers to, in either direction, de-duplicated. */\nexport function dynamicListRuleListIds(rule: DynamicListRule): string[] {\n const ids = new Set<string>()\n for (const dimensions of allDimensions(rule)) {\n for (const listId of dimensions.inListIds ?? []) ids.add(listId)\n for (const listId of dimensions.notInListIds ?? []) ids.add(listId)\n }\n return [...ids]\n}\n\n/*==========================================\n * A SAVED CONTACTS VIEW, IN THIS LANGUAGE (AGL-2617).\n *\n * A view stores the Contacts list's own filter clauses — a field, an\n * operator, a value — and an audience rule stores dimensions. The two are\n * different vocabularies for overlapping questions: \"owner is Dana\" is an\n * `ownerUids` dimension, \"tagged vip or wholesale\" is a `tags` dimension,\n * \"created after June\" is `createdAfterMs`. So a view is USABLE as an\n * audience exactly as far as its clauses have a dimension here, and the\n * translation below is the whole of that claim: it is pure, it names every\n * clause it could not carry, and nothing about a view is matched any other\n * way. The alternative — evaluating the list's grammar inside the sweep —\n * would put a second matcher beside the one the console runs, in a module\n * that may not import the grammar's home.\n *\n * A clause with no dimension is UNSUPPORTED, never dropped. A name prefix,\n * an email, an `updatedAt` window, a form id: dropping one would make the\n * audience wider than the view it was picked as, and a campaign going to\n * the wrong people is the failure every part of this feature is shaped to\n * prevent. The picker offers only views that translate whole, and the\n * materializer treats a stored reference to one that does not the way it\n * treats a deleted segment.\n *=========================================*/\n\n/** What a view's filters became — see the section note. */\nexport interface DynamicListViewTranslation {\n dimensions: DynamicListDimensions\n /** The clauses this language has no dimension for. Empty means an audience. */\n unsupported: CrmViewFilterClause[]\n}\n\nconst DAY_MS = 86_400_000\n\n/** The values an `isAnyOf` carries, or the one an equality does; `null` for any other operator. */\nconst viewClauseValues = (clause: CrmViewFilterClause): string[] | null => {\n const value = clause.value.trim()\n if (clause.op === 'isAnyOf') {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n }\n if (clause.op === 'equals' || clause.op === 'is' || clause.op === 'contains') {\n return value ? [value] : []\n }\n return null\n}\n\nconst CUSTOM_VIEW_OPS: Readonly<Record<string, DynamicListCustomOp>> = {\n equals: 'eq',\n is: 'eq',\n '=': 'eq',\n doesNotEqual: 'neq',\n '!=': 'neq',\n contains: 'contains',\n '>': 'gt',\n '<': 'lt',\n isNotEmpty: 'set',\n isEmpty: 'unset',\n}\n\n/**\n * A view's filters as the dimensions of one AND-block, and the clauses\n * that could not be.\n *\n * Every list operator keeps its own meaning across the translation:\n * `isAnyOf` is the OR the dimension lists already are, an equality is a\n * list of one, a `contains` on the tag array is one tag matched whole. The\n * dates read the clause's value as an instant — a day, as the filter bar\n * writes one — with `after` and `onOrBefore` stepping a day past it the\n * way the list's own matcher does. A purchase threshold has a floor here\n * and no ceiling, so `at least` and `over` carry and `under` cannot.\n */\nexport function dynamicListDimensionsForCrmView(\n filters: readonly CrmViewFilterClause[],\n): DynamicListViewTranslation {\n const fields = CRM_CONTACT_VIEW_FIELDS\n const dimensions: DynamicListDimensions = {}\n const unsupported: CrmViewFilterClause[] = []\n const behavior: DynamicListBehavior = {}\n const custom: DynamicListCustomClause[] = []\n const extend = (\n key: 'tags' | 'ownerUids' | 'companyIds',\n values: string[],\n ) => {\n dimensions[key] = [...(dimensions[key] ?? []), ...values]\n }\n\n for (const clause of filters) {\n const values = viewClauseValues(clause)\n const value = clause.value.trim()\n const customKey = crmContactCustomKey(clause.field)\n if (customKey !== null) {\n const key = normalizeContactFieldKey(customKey)\n const op = CUSTOM_VIEW_OPS[clause.op]\n if (key && op) {\n custom.push(\n op === 'set' || op === 'unset' ? { key, op } : { key, op, value },\n )\n continue\n }\n unsupported.push(clause)\n continue\n }\n switch (clause.field) {\n case fields.tags:\n if (values?.length) {\n extend('tags', values.map((tag) => tag.toLowerCase()))\n continue\n }\n break\n case fields.source:\n if (values?.length) {\n const sources = values.filter(\n (source): source is ContactSource => source in CONTACT_SOURCE_LABELS,\n )\n if (sources.length === values.length) {\n dimensions.captureSources = [\n ...(dimensions.captureSources ?? []),\n ...sources,\n ]\n continue\n }\n }\n break\n case fields.owner:\n if (values?.length) {\n extend('ownerUids', values)\n continue\n }\n break\n case fields.stage:\n if (values?.length && values.every(isContactLifecycleStage)) {\n dimensions.lifecycleStages = [\n ...(dimensions.lifecycleStages ?? []),\n ...(values as ContactLifecycleStage[]),\n ]\n continue\n }\n break\n case fields.company:\n if (values?.length) {\n extend('companyIds', values)\n continue\n }\n break\n case fields.createdAt: {\n const at = Date.parse(value)\n if (Number.isFinite(at)) {\n if (clause.op === 'after') dimensions.createdAfterMs = at + DAY_MS\n else if (clause.op === 'onOrAfter') dimensions.createdAfterMs = at\n else if (clause.op === 'before') dimensions.createdBeforeMs = at\n else if (clause.op === 'onOrBefore') {\n dimensions.createdBeforeMs = at + DAY_MS\n } else if (clause.op === 'is') {\n dimensions.createdAfterMs = at\n dimensions.createdBeforeMs = at + DAY_MS\n } else break\n continue\n }\n break\n }\n case fields.orders:\n case fields.ltv: {\n const amount = Number(value)\n if (Number.isFinite(amount) && (clause.op === '>=' || clause.op === '>')) {\n const floor = clause.op === '>' ? amount + 1 : amount\n if (clause.field === fields.orders) behavior.ordersCountAtLeast = floor\n else behavior.ltvCentsAtLeast = floor\n continue\n }\n break\n }\n default:\n break\n }\n unsupported.push(clause)\n }\n\n if (Object.keys(behavior).length) dimensions.behavior = behavior\n if (custom.length) dimensions.custom = custom\n return { dimensions, unsupported }\n}\n\n/**\n * The rule the sweep PLANS with once a view is resolved: the rule itself\n * with the view's block beside its branches, so the planners that read\n * every block — does this need the contact facet, an engagement lookup, a\n * list membership — see the view's dimensions too. For planning only; the\n * matcher takes the view as its own option, because a branch is OR and a\n * view is AND.\n */\nexport function dynamicListPlanningRule(\n rule: DynamicListRule,\n view: DynamicListDimensions | null,\n): DynamicListRule {\n if (!view || Object.keys(view).length === 0) return rule\n return { ...rule, any: [...(rule.any ?? []), view] }\n}\n"],"names":["normalizeCampaignIds","CONTACT_SOURCE_LABELS","contactMatchesSegment","isContactLifecycleStage","normalizeContactFieldKey","CRM_CONTACT_VIEW_FIELDS","crmContactCustomKey","CAMPAIGN_MEMBER_SILOS","DYNAMIC_LIST_CUSTOM_OPS","VALUED_CUSTOM_OPS","Set","DYNAMIC_LIST_MAX_CUSTOM_CLAUSES","asStringArray","value","Array","isArray","map","entry","String","trim","filter","length","slice","asPositiveNumber","parsed","Number","isFinite","undefined","DYNAMIC_LIST_SOURCES","DYNAMIC_LIST_MAX_GROUPS","DYNAMIC_LIST_MAX_LIST_REFERENCES","normalizeCustomClause","raw","key","op","includes","operator","has","trimmed","normalizeDimensions","behavior","normalizedBehavior","ordersCountAtLeast","ltvCentsAtLeast","lastPurchaseWithinDays","noPurchaseForDays","engagement","normalizedEngagement","openedWithinDays","clickedWithinDays","notOpenedForDays","notClickedForDays","tags","captureSources","formNames","campaignIds","createdAfterMs","createdBeforeMs","inListIds","notInListIds","ownerUids","lifecycleStages","companyIds","custom","clause","engagedWithinDays","Object","keys","dimensionsAreEmpty","dimensions","normalizeDynamicListRule","stored","sources","source","segmentId","viewId","groups","negate","group","stripNegate","any","dynamicListRuleIsEmpty","rule","candidateMatchesDynamicListRule","candidate","options","silo","top","matchesDimensions","segment","nowMs","view","some","matched","day","createdAtMs","wanted","name","toLowerCase","formName","filed","campaignId","segmentFilters","ordersCount","ltvCents","last","lastPurchaseAtMs","ownerUid","lifecycleStage","companyId","customValueMatches","lastEmailEngagementAtMs","opened","lastOpenedAtMs","clicked","lastClickedAtMs","memberOf","listIds","every","listId","customValueIsSet","customValueText","present","left","right","numeric","a","b","allDimensions","dynamicListRuleNeedsContactFacet","dynamicListRuleNeedsEngagement","dynamicListRuleNeedsCampaigns","dynamicListRuleWithoutListReference","strip","id","next","stripped","dynamicListRuleListIds","ids","add","DAY_MS","viewClauseValues","split","Boolean","CUSTOM_VIEW_OPS","equals","is","doesNotEqual","contains","isNotEmpty","isEmpty","dynamicListDimensionsForCrmView","filters","fields","unsupported","extend","values","customKey","field","push","tag","owner","stage","company","createdAt","at","Date","parse","orders","ltv","amount","floor","dynamicListPlanningRule"],"mappings":"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"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Element animation vocabulary (AGL-2486) — the names the renderer, the
|
|
19
|
+
* besigner attributes panel and the tenant's stylesheet all agree on.
|
|
20
|
+
*
|
|
21
|
+
* ## Why there is no animation runtime here
|
|
22
|
+
*
|
|
23
|
+
* Published pages ship no animation library, and that is the design, not a
|
|
24
|
+
* phase one. Motion's smallest useful React surface (`LazyMotion` +
|
|
25
|
+
* `domAnimation` + `m`) is ~17kB gzipped and the full `motion` import ~34kB —
|
|
26
|
+
* against the 87,646 B gzipped that came OFF the published page the same week
|
|
27
|
+
* this landed. What a site builder's authors actually reach for is entrance
|
|
28
|
+
* and hover emphasis: fade, slide, zoom, played on load, on scroll-in or on
|
|
29
|
+
* hover. Every one of those is `@keyframes` plus `transition`, which the
|
|
30
|
+
* compositor runs off the main thread — including during hydration, which is
|
|
31
|
+
* exactly when an entrance animation plays and exactly when a JS runtime is
|
|
32
|
+
* least able to keep up. Spring physics, FLIP/layout animation and
|
|
33
|
+
* gesture-driven interpolation are what a runtime would buy, and none of them
|
|
34
|
+
* are authorable from a preset dropdown by the audience this is for.
|
|
35
|
+
*
|
|
36
|
+
* The single exception is the scroll trigger, which needs an
|
|
37
|
+
* `IntersectionObserver`. That is ~700 bytes of inline script shipped in the
|
|
38
|
+
* SSR HTML by `apps/tenant`, only on pages that actually carry a
|
|
39
|
+
* scroll-triggered node — no module, no chunk, no extra request, and it
|
|
40
|
+
* gzips with the document. See `@aglyn/tenant-runtime`'s
|
|
41
|
+
* `element-animation-assets.ts` for the stylesheet and that script.
|
|
42
|
+
*
|
|
43
|
+
* This module is reachable from the client bundle (the renderer's `Leaf`
|
|
44
|
+
* imports it), so it holds constants and two small pure functions and
|
|
45
|
+
* nothing else. The stylesheet text deliberately lives in the server-only
|
|
46
|
+
* module so a page that animates nothing pays literally zero bytes for it.
|
|
47
|
+
*/
|
|
48
|
+
/** Preset id prop. Reserved node prop, stripped before the DOM spread. */
|
|
49
|
+
export declare const NODE_ANIMATION_PROP = "aglynAnimation";
|
|
50
|
+
/** Trigger prop: when the preset plays. */
|
|
51
|
+
export declare const NODE_ANIMATION_TRIGGER_PROP = "aglynAnimationTrigger";
|
|
52
|
+
/** Duration prop, in milliseconds. */
|
|
53
|
+
export declare const NODE_ANIMATION_DURATION_PROP = "aglynAnimationDuration";
|
|
54
|
+
/** Delay prop, in milliseconds. */
|
|
55
|
+
export declare const NODE_ANIMATION_DELAY_PROP = "aglynAnimationDelay";
|
|
56
|
+
/** Repeat prop: re-play every time the element scrolls back into view. */
|
|
57
|
+
export declare const NODE_ANIMATION_REPEAT_PROP = "aglynAnimationRepeat";
|
|
58
|
+
/** Easing prop: the shape of the motion curve. */
|
|
59
|
+
export declare const NODE_ANIMATION_EASE_PROP = "aglynAnimationEase";
|
|
60
|
+
/** Stagger prop: animate the children one after another, not the element. */
|
|
61
|
+
export declare const NODE_ANIMATION_STAGGER_PROP = "aglynAnimationStagger";
|
|
62
|
+
/** Stagger step prop: how much later each child starts, in milliseconds. */
|
|
63
|
+
export declare const NODE_ANIMATION_STAGGER_STEP_PROP = "aglynAnimationStaggerStep";
|
|
64
|
+
/** Every reserved animation prop, for the renderer's strip step. */
|
|
65
|
+
export declare const NODE_ANIMATION_PROPS: readonly ["aglynAnimation", "aglynAnimationTrigger", "aglynAnimationDuration", "aglynAnimationDelay", "aglynAnimationRepeat", "aglynAnimationEase", "aglynAnimationStagger", "aglynAnimationStaggerStep"];
|
|
66
|
+
/**
|
|
67
|
+
* The "no animation" value is a real string, never `''` (AGL-1451): an empty
|
|
68
|
+
* value cannot persist through the attributes form, so an author who picked a
|
|
69
|
+
* preset could never switch back off it.
|
|
70
|
+
*/
|
|
71
|
+
export declare const ANIMATION_NONE = "none";
|
|
72
|
+
/** Preset ids. Persisted in screen documents — never rename one. */
|
|
73
|
+
export declare const ANIMATION_PRESETS: readonly ["none", "fade", "slide-up", "slide-down", "slide-left", "slide-right", "zoom-in", "zoom-out"];
|
|
74
|
+
export type AnimationPreset = (typeof ANIMATION_PRESETS)[number];
|
|
75
|
+
/** Trigger ids. Persisted — never rename one. */
|
|
76
|
+
export declare const ANIMATION_TRIGGERS: readonly ["load", "scroll", "hover"];
|
|
77
|
+
export type AnimationTrigger = (typeof ANIMATION_TRIGGERS)[number];
|
|
78
|
+
/**
|
|
79
|
+
* Easing ids — the SHAPE of the motion, the third dial beside duration and
|
|
80
|
+
* delay. Persisted; never rename one.
|
|
81
|
+
*
|
|
82
|
+
* Only the ids live here. The `cubic-bezier()` curves themselves are in the
|
|
83
|
+
* server-only stylesheet module, for the same reason the keyframes are: this
|
|
84
|
+
* file is reachable from the client bundle and six bezier literals is ~200
|
|
85
|
+
* bytes that every visitor to a still page would otherwise carry. The id
|
|
86
|
+
* becomes a class, the class sets a custom property, and the curve is read
|
|
87
|
+
* from the sheet that only an animating page ships.
|
|
88
|
+
*/
|
|
89
|
+
export declare const ANIMATION_EASINGS: readonly ["smooth", "steady", "gentle-start", "gentle-end", "gentle-both", "overshoot"];
|
|
90
|
+
export type AnimationEase = (typeof ANIMATION_EASINGS)[number];
|
|
91
|
+
/** Default when an author picks a preset but leaves the dials alone. */
|
|
92
|
+
export declare const ANIMATION_DEFAULT_TRIGGER: AnimationTrigger;
|
|
93
|
+
export declare const ANIMATION_DEFAULT_DURATION_MS = 600;
|
|
94
|
+
export declare const ANIMATION_DEFAULT_DELAY_MS = 0;
|
|
95
|
+
/**
|
|
96
|
+
* The curve every animation used before easing was authorable. Keeping it as
|
|
97
|
+
* the default means every screen authored before this shipped renders byte
|
|
98
|
+
* for byte the same.
|
|
99
|
+
*/
|
|
100
|
+
export declare const ANIMATION_DEFAULT_EASE: AnimationEase;
|
|
101
|
+
/** Default gap between staggered children. */
|
|
102
|
+
export declare const ANIMATION_DEFAULT_STAGGER_STEP_MS = 90;
|
|
103
|
+
/** Upper bounds. A 30s entrance is an author mistake, not an intent. */
|
|
104
|
+
export declare const ANIMATION_MAX_DURATION_MS = 3000;
|
|
105
|
+
export declare const ANIMATION_MAX_DELAY_MS = 3000;
|
|
106
|
+
/**
|
|
107
|
+
* A stagger step is capped far lower than a delay, because it MULTIPLIES:
|
|
108
|
+
* the last of twelve cards waits eleven steps. At the 500ms cap that is
|
|
109
|
+
* already 5.5s, which is why {@link ANIMATION_STAGGER_MAX_CHILDREN} stops the
|
|
110
|
+
* ladder climbing rather than letting a long list run off the end.
|
|
111
|
+
*/
|
|
112
|
+
export declare const ANIMATION_MAX_STAGGER_STEP_MS = 500;
|
|
113
|
+
/**
|
|
114
|
+
* How many children get their own rung of the stagger ladder. Beyond this
|
|
115
|
+
* every remaining child shares the last rung, so a 200-row collection cannot
|
|
116
|
+
* leave its tail invisible for a minute — the tail arrives together, which is
|
|
117
|
+
* the least surprising failure and the one an author can actually see.
|
|
118
|
+
*
|
|
119
|
+
* Also the size of the generated rule block, which is why it is a number and
|
|
120
|
+
* not "all of them": each rung is one selector.
|
|
121
|
+
*/
|
|
122
|
+
export declare const ANIMATION_STAGGER_MAX_CHILDREN = 24;
|
|
123
|
+
/** Base class every animated element carries. */
|
|
124
|
+
export declare const ANIMATION_CLASS = "aglyn-anim";
|
|
125
|
+
/**
|
|
126
|
+
* Base class of a STAGGER HOST — an element whose children animate one after
|
|
127
|
+
* another instead of the element itself animating.
|
|
128
|
+
*
|
|
129
|
+
* It is a different base class rather than a modifier on {@link
|
|
130
|
+
* ANIMATION_CLASS} because the two are mutually exclusive by construction: an
|
|
131
|
+
* element carrying both would play its own entrance AND run its children's,
|
|
132
|
+
* which is two overlapping fades on the same pixels. The preset and easing
|
|
133
|
+
* modifiers are shared, and reach the children through custom-property
|
|
134
|
+
* inheritance — the host sets `--aglyn-anim-name`, every child reads it, and
|
|
135
|
+
* the stylesheet needs no per-preset child rule.
|
|
136
|
+
*/
|
|
137
|
+
export declare const ANIMATION_GROUP_CLASS = "aglyn-anim-group";
|
|
138
|
+
/** Per-preset modifier, e.g. `aglyn-anim--slide-up`. */
|
|
139
|
+
export declare const ANIMATION_PRESET_CLASS_PREFIX = "aglyn-anim--";
|
|
140
|
+
/** Per-easing modifier, e.g. `aglyn-anim-ease--overshoot`. */
|
|
141
|
+
export declare const ANIMATION_EASE_CLASS_PREFIX = "aglyn-anim-ease--";
|
|
142
|
+
/** Added by the scroll runtime once an element has entered the viewport. */
|
|
143
|
+
export declare const ANIMATION_IN_CLASS = "aglyn-anim--in";
|
|
144
|
+
/**
|
|
145
|
+
* Set on `<html>` by the inline runtime. Every rule that HIDES a
|
|
146
|
+
* scroll-triggered element before it plays is scoped under this class, so a
|
|
147
|
+
* visitor with no JS — and every crawler — sees the un-animated, VISIBLE
|
|
148
|
+
* state. Nothing is ever hidden by the server.
|
|
149
|
+
*/
|
|
150
|
+
export declare const ANIMATION_READY_CLASS = "aglyn-anim-js";
|
|
151
|
+
/** Trigger attribute the stylesheet and the runtime both select on. */
|
|
152
|
+
export declare const ANIMATION_TRIGGER_ATTR = "data-aglyn-anim-trigger";
|
|
153
|
+
/** Repeat attribute the runtime reads; `'1'` means re-play. */
|
|
154
|
+
export declare const ANIMATION_REPEAT_ATTR = "data-aglyn-anim-repeat";
|
|
155
|
+
/** Custom properties carrying the author's dials. */
|
|
156
|
+
export declare const ANIMATION_DURATION_VAR = "--aglyn-anim-duration";
|
|
157
|
+
export declare const ANIMATION_DELAY_VAR = "--aglyn-anim-delay";
|
|
158
|
+
/** Set on a stagger host; every child reads it through inheritance. */
|
|
159
|
+
export declare const ANIMATION_STAGGER_STEP_VAR = "--aglyn-anim-step";
|
|
160
|
+
/**
|
|
161
|
+
* Set on each child BY the stylesheet's nth-child ladder, not by the
|
|
162
|
+
* renderer — the renderer never sees a child's index, and asking it to would
|
|
163
|
+
* mean the host re-rendering whenever a sibling was inserted.
|
|
164
|
+
*/
|
|
165
|
+
export declare const ANIMATION_STAGGER_OFFSET_VAR = "--aglyn-anim-stagger";
|
|
166
|
+
export interface ResolvedElementAnimation {
|
|
167
|
+
preset: AnimationPreset;
|
|
168
|
+
trigger: AnimationTrigger;
|
|
169
|
+
ease: AnimationEase;
|
|
170
|
+
durationMs: number;
|
|
171
|
+
delayMs: number;
|
|
172
|
+
repeat: boolean;
|
|
173
|
+
/** True when the CHILDREN animate in sequence rather than this element. */
|
|
174
|
+
stagger: boolean;
|
|
175
|
+
staggerStepMs: number;
|
|
176
|
+
/** Classes to append to the element. */
|
|
177
|
+
className: string;
|
|
178
|
+
/** DOM attributes the stylesheet and runtime select on. */
|
|
179
|
+
attributes: Record<string, string>;
|
|
180
|
+
/** Custom properties, merged into the element's inline style. */
|
|
181
|
+
style: Record<string, string>;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Reads the reserved animation props off a node's resolved props and returns
|
|
185
|
+
* the class/attribute/style triple the renderer applies — or `undefined` when
|
|
186
|
+
* the node does not animate, which is the overwhelmingly common case and
|
|
187
|
+
* costs one property read.
|
|
188
|
+
*
|
|
189
|
+
* Unknown preset and trigger values resolve to "no animation" rather than
|
|
190
|
+
* being passed through: these strings reach a `data-` attribute and a class
|
|
191
|
+
* name, and a screen document authored against a future preset must degrade
|
|
192
|
+
* to a static element, never to a broken selector.
|
|
193
|
+
*/
|
|
194
|
+
export declare function resolveElementAnimation(props: Record<string, any> | undefined): ResolvedElementAnimation | undefined;
|
|
195
|
+
/**
|
|
196
|
+
* True when a node's props ask for a real animation. Cheap enough to run over
|
|
197
|
+
* every node in a screen's flat node map, which is how the tenant decides
|
|
198
|
+
* whether to ship the stylesheet at all.
|
|
199
|
+
*/
|
|
200
|
+
export declare function nodePropsAnimate(props: Record<string, any> | undefined): boolean;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* Element animation vocabulary (AGL-2486) — the names the renderer, the
|
|
18
|
+
* besigner attributes panel and the tenant's stylesheet all agree on.
|
|
19
|
+
*
|
|
20
|
+
* ## Why there is no animation runtime here
|
|
21
|
+
*
|
|
22
|
+
* Published pages ship no animation library, and that is the design, not a
|
|
23
|
+
* phase one. Motion's smallest useful React surface (`LazyMotion` +
|
|
24
|
+
* `domAnimation` + `m`) is ~17kB gzipped and the full `motion` import ~34kB —
|
|
25
|
+
* against the 87,646 B gzipped that came OFF the published page the same week
|
|
26
|
+
* this landed. What a site builder's authors actually reach for is entrance
|
|
27
|
+
* and hover emphasis: fade, slide, zoom, played on load, on scroll-in or on
|
|
28
|
+
* hover. Every one of those is `@keyframes` plus `transition`, which the
|
|
29
|
+
* compositor runs off the main thread — including during hydration, which is
|
|
30
|
+
* exactly when an entrance animation plays and exactly when a JS runtime is
|
|
31
|
+
* least able to keep up. Spring physics, FLIP/layout animation and
|
|
32
|
+
* gesture-driven interpolation are what a runtime would buy, and none of them
|
|
33
|
+
* are authorable from a preset dropdown by the audience this is for.
|
|
34
|
+
*
|
|
35
|
+
* The single exception is the scroll trigger, which needs an
|
|
36
|
+
* `IntersectionObserver`. That is ~700 bytes of inline script shipped in the
|
|
37
|
+
* SSR HTML by `apps/tenant`, only on pages that actually carry a
|
|
38
|
+
* scroll-triggered node — no module, no chunk, no extra request, and it
|
|
39
|
+
* gzips with the document. See `@aglyn/tenant-runtime`'s
|
|
40
|
+
* `element-animation-assets.ts` for the stylesheet and that script.
|
|
41
|
+
*
|
|
42
|
+
* This module is reachable from the client bundle (the renderer's `Leaf`
|
|
43
|
+
* imports it), so it holds constants and two small pure functions and
|
|
44
|
+
* nothing else. The stylesheet text deliberately lives in the server-only
|
|
45
|
+
* module so a page that animates nothing pays literally zero bytes for it.
|
|
46
|
+
*/ /** Preset id prop. Reserved node prop, stripped before the DOM spread. */ export const NODE_ANIMATION_PROP = 'aglynAnimation';
|
|
47
|
+
/** Trigger prop: when the preset plays. */ export const NODE_ANIMATION_TRIGGER_PROP = 'aglynAnimationTrigger';
|
|
48
|
+
/** Duration prop, in milliseconds. */ export const NODE_ANIMATION_DURATION_PROP = 'aglynAnimationDuration';
|
|
49
|
+
/** Delay prop, in milliseconds. */ export const NODE_ANIMATION_DELAY_PROP = 'aglynAnimationDelay';
|
|
50
|
+
/** Repeat prop: re-play every time the element scrolls back into view. */ export const NODE_ANIMATION_REPEAT_PROP = 'aglynAnimationRepeat';
|
|
51
|
+
/** Easing prop: the shape of the motion curve. */ export const NODE_ANIMATION_EASE_PROP = 'aglynAnimationEase';
|
|
52
|
+
/** Stagger prop: animate the children one after another, not the element. */ export const NODE_ANIMATION_STAGGER_PROP = 'aglynAnimationStagger';
|
|
53
|
+
/** Stagger step prop: how much later each child starts, in milliseconds. */ export const NODE_ANIMATION_STAGGER_STEP_PROP = 'aglynAnimationStaggerStep';
|
|
54
|
+
/** Every reserved animation prop, for the renderer's strip step. */ export const NODE_ANIMATION_PROPS = [
|
|
55
|
+
NODE_ANIMATION_PROP,
|
|
56
|
+
NODE_ANIMATION_TRIGGER_PROP,
|
|
57
|
+
NODE_ANIMATION_DURATION_PROP,
|
|
58
|
+
NODE_ANIMATION_DELAY_PROP,
|
|
59
|
+
NODE_ANIMATION_REPEAT_PROP,
|
|
60
|
+
NODE_ANIMATION_EASE_PROP,
|
|
61
|
+
NODE_ANIMATION_STAGGER_PROP,
|
|
62
|
+
NODE_ANIMATION_STAGGER_STEP_PROP
|
|
63
|
+
];
|
|
64
|
+
/**
|
|
65
|
+
* The "no animation" value is a real string, never `''` (AGL-1451): an empty
|
|
66
|
+
* value cannot persist through the attributes form, so an author who picked a
|
|
67
|
+
* preset could never switch back off it.
|
|
68
|
+
*/ export const ANIMATION_NONE = 'none';
|
|
69
|
+
/** Preset ids. Persisted in screen documents — never rename one. */ export const ANIMATION_PRESETS = [
|
|
70
|
+
ANIMATION_NONE,
|
|
71
|
+
'fade',
|
|
72
|
+
'slide-up',
|
|
73
|
+
'slide-down',
|
|
74
|
+
'slide-left',
|
|
75
|
+
'slide-right',
|
|
76
|
+
'zoom-in',
|
|
77
|
+
'zoom-out'
|
|
78
|
+
];
|
|
79
|
+
/** Trigger ids. Persisted — never rename one. */ export const ANIMATION_TRIGGERS = [
|
|
80
|
+
'load',
|
|
81
|
+
'scroll',
|
|
82
|
+
'hover'
|
|
83
|
+
];
|
|
84
|
+
/**
|
|
85
|
+
* Easing ids — the SHAPE of the motion, the third dial beside duration and
|
|
86
|
+
* delay. Persisted; never rename one.
|
|
87
|
+
*
|
|
88
|
+
* Only the ids live here. The `cubic-bezier()` curves themselves are in the
|
|
89
|
+
* server-only stylesheet module, for the same reason the keyframes are: this
|
|
90
|
+
* file is reachable from the client bundle and six bezier literals is ~200
|
|
91
|
+
* bytes that every visitor to a still page would otherwise carry. The id
|
|
92
|
+
* becomes a class, the class sets a custom property, and the curve is read
|
|
93
|
+
* from the sheet that only an animating page ships.
|
|
94
|
+
*/ export const ANIMATION_EASINGS = [
|
|
95
|
+
'smooth',
|
|
96
|
+
'steady',
|
|
97
|
+
'gentle-start',
|
|
98
|
+
'gentle-end',
|
|
99
|
+
'gentle-both',
|
|
100
|
+
'overshoot'
|
|
101
|
+
];
|
|
102
|
+
/** Default when an author picks a preset but leaves the dials alone. */ export const ANIMATION_DEFAULT_TRIGGER = 'scroll';
|
|
103
|
+
export const ANIMATION_DEFAULT_DURATION_MS = 600;
|
|
104
|
+
export const ANIMATION_DEFAULT_DELAY_MS = 0;
|
|
105
|
+
/**
|
|
106
|
+
* The curve every animation used before easing was authorable. Keeping it as
|
|
107
|
+
* the default means every screen authored before this shipped renders byte
|
|
108
|
+
* for byte the same.
|
|
109
|
+
*/ export const ANIMATION_DEFAULT_EASE = 'smooth';
|
|
110
|
+
/** Default gap between staggered children. */ export const ANIMATION_DEFAULT_STAGGER_STEP_MS = 90;
|
|
111
|
+
/** Upper bounds. A 30s entrance is an author mistake, not an intent. */ export const ANIMATION_MAX_DURATION_MS = 3000;
|
|
112
|
+
export const ANIMATION_MAX_DELAY_MS = 3000;
|
|
113
|
+
/**
|
|
114
|
+
* A stagger step is capped far lower than a delay, because it MULTIPLIES:
|
|
115
|
+
* the last of twelve cards waits eleven steps. At the 500ms cap that is
|
|
116
|
+
* already 5.5s, which is why {@link ANIMATION_STAGGER_MAX_CHILDREN} stops the
|
|
117
|
+
* ladder climbing rather than letting a long list run off the end.
|
|
118
|
+
*/ export const ANIMATION_MAX_STAGGER_STEP_MS = 500;
|
|
119
|
+
/**
|
|
120
|
+
* How many children get their own rung of the stagger ladder. Beyond this
|
|
121
|
+
* every remaining child shares the last rung, so a 200-row collection cannot
|
|
122
|
+
* leave its tail invisible for a minute — the tail arrives together, which is
|
|
123
|
+
* the least surprising failure and the one an author can actually see.
|
|
124
|
+
*
|
|
125
|
+
* Also the size of the generated rule block, which is why it is a number and
|
|
126
|
+
* not "all of them": each rung is one selector.
|
|
127
|
+
*/ export const ANIMATION_STAGGER_MAX_CHILDREN = 24;
|
|
128
|
+
/** Base class every animated element carries. */ export const ANIMATION_CLASS = 'aglyn-anim';
|
|
129
|
+
/**
|
|
130
|
+
* Base class of a STAGGER HOST — an element whose children animate one after
|
|
131
|
+
* another instead of the element itself animating.
|
|
132
|
+
*
|
|
133
|
+
* It is a different base class rather than a modifier on {@link
|
|
134
|
+
* ANIMATION_CLASS} because the two are mutually exclusive by construction: an
|
|
135
|
+
* element carrying both would play its own entrance AND run its children's,
|
|
136
|
+
* which is two overlapping fades on the same pixels. The preset and easing
|
|
137
|
+
* modifiers are shared, and reach the children through custom-property
|
|
138
|
+
* inheritance — the host sets `--aglyn-anim-name`, every child reads it, and
|
|
139
|
+
* the stylesheet needs no per-preset child rule.
|
|
140
|
+
*/ export const ANIMATION_GROUP_CLASS = 'aglyn-anim-group';
|
|
141
|
+
/** Per-preset modifier, e.g. `aglyn-anim--slide-up`. */ export const ANIMATION_PRESET_CLASS_PREFIX = 'aglyn-anim--';
|
|
142
|
+
/** Per-easing modifier, e.g. `aglyn-anim-ease--overshoot`. */ export const ANIMATION_EASE_CLASS_PREFIX = 'aglyn-anim-ease--';
|
|
143
|
+
/** Added by the scroll runtime once an element has entered the viewport. */ export const ANIMATION_IN_CLASS = 'aglyn-anim--in';
|
|
144
|
+
/**
|
|
145
|
+
* Set on `<html>` by the inline runtime. Every rule that HIDES a
|
|
146
|
+
* scroll-triggered element before it plays is scoped under this class, so a
|
|
147
|
+
* visitor with no JS — and every crawler — sees the un-animated, VISIBLE
|
|
148
|
+
* state. Nothing is ever hidden by the server.
|
|
149
|
+
*/ export const ANIMATION_READY_CLASS = 'aglyn-anim-js';
|
|
150
|
+
/** Trigger attribute the stylesheet and the runtime both select on. */ export const ANIMATION_TRIGGER_ATTR = 'data-aglyn-anim-trigger';
|
|
151
|
+
/** Repeat attribute the runtime reads; `'1'` means re-play. */ export const ANIMATION_REPEAT_ATTR = 'data-aglyn-anim-repeat';
|
|
152
|
+
/** Custom properties carrying the author's dials. */ export const ANIMATION_DURATION_VAR = '--aglyn-anim-duration';
|
|
153
|
+
export const ANIMATION_DELAY_VAR = '--aglyn-anim-delay';
|
|
154
|
+
/** Set on a stagger host; every child reads it through inheritance. */ export const ANIMATION_STAGGER_STEP_VAR = '--aglyn-anim-step';
|
|
155
|
+
/**
|
|
156
|
+
* Set on each child BY the stylesheet's nth-child ladder, not by the
|
|
157
|
+
* renderer — the renderer never sees a child's index, and asking it to would
|
|
158
|
+
* mean the host re-rendering whenever a sibling was inserted.
|
|
159
|
+
*/ export const ANIMATION_STAGGER_OFFSET_VAR = '--aglyn-anim-stagger';
|
|
160
|
+
/**
|
|
161
|
+
* Clamp a millisecond dial. `strictNullChecks` is OFF repo-wide and `0` is a
|
|
162
|
+
* legitimate delay, so this tests for a finite number rather than
|
|
163
|
+
* truthiness — `if (!delay)` would silently discard a deliberate `0` and,
|
|
164
|
+
* worse, treat it as "not set" and substitute the default.
|
|
165
|
+
*/ function clampMs(value, fallback, max) {
|
|
166
|
+
const n = typeof value === 'string' ? Number(value) : value;
|
|
167
|
+
if (typeof n !== 'number' || !Number.isFinite(n)) return fallback;
|
|
168
|
+
return Math.min(Math.max(n, 0), max);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Reads the reserved animation props off a node's resolved props and returns
|
|
172
|
+
* the class/attribute/style triple the renderer applies — or `undefined` when
|
|
173
|
+
* the node does not animate, which is the overwhelmingly common case and
|
|
174
|
+
* costs one property read.
|
|
175
|
+
*
|
|
176
|
+
* Unknown preset and trigger values resolve to "no animation" rather than
|
|
177
|
+
* being passed through: these strings reach a `data-` attribute and a class
|
|
178
|
+
* name, and a screen document authored against a future preset must degrade
|
|
179
|
+
* to a static element, never to a broken selector.
|
|
180
|
+
*/ export function resolveElementAnimation(props) {
|
|
181
|
+
const preset = props == null ? void 0 : props[NODE_ANIMATION_PROP];
|
|
182
|
+
if (typeof preset !== 'string' || preset === ANIMATION_NONE) return undefined;
|
|
183
|
+
if (!ANIMATION_PRESETS.includes(preset)) return undefined;
|
|
184
|
+
const rawTrigger = props == null ? void 0 : props[NODE_ANIMATION_TRIGGER_PROP];
|
|
185
|
+
const trigger = typeof rawTrigger === 'string' && ANIMATION_TRIGGERS.includes(rawTrigger) ? rawTrigger : ANIMATION_DEFAULT_TRIGGER;
|
|
186
|
+
const durationMs = clampMs(props == null ? void 0 : props[NODE_ANIMATION_DURATION_PROP], ANIMATION_DEFAULT_DURATION_MS, ANIMATION_MAX_DURATION_MS);
|
|
187
|
+
const delayMs = clampMs(props == null ? void 0 : props[NODE_ANIMATION_DELAY_PROP], ANIMATION_DEFAULT_DELAY_MS, ANIMATION_MAX_DELAY_MS);
|
|
188
|
+
const rawEase = props == null ? void 0 : props[NODE_ANIMATION_EASE_PROP];
|
|
189
|
+
const ease = typeof rawEase === 'string' && ANIMATION_EASINGS.includes(rawEase) ? rawEase : ANIMATION_DEFAULT_EASE;
|
|
190
|
+
// Repeat only means anything for the scroll trigger — `load` fires once by
|
|
191
|
+
// definition and `hover` is a transition, not a keyframe run.
|
|
192
|
+
const repeat = trigger === 'scroll' && Boolean(props == null ? void 0 : props[NODE_ANIMATION_REPEAT_PROP]);
|
|
193
|
+
// Stagger is refused for `hover` on purpose. A hover effect is a transition
|
|
194
|
+
// that must reverse the instant the pointer leaves; a staggered one would
|
|
195
|
+
// leave half a row mid-flight, and the ladder below only ever feeds
|
|
196
|
+
// `animation-delay`, which a transition does not read.
|
|
197
|
+
const stagger = trigger !== 'hover' && Boolean(props == null ? void 0 : props[NODE_ANIMATION_STAGGER_PROP]);
|
|
198
|
+
const staggerStepMs = stagger ? clampMs(props == null ? void 0 : props[NODE_ANIMATION_STAGGER_STEP_PROP], ANIMATION_DEFAULT_STAGGER_STEP_MS, ANIMATION_MAX_STAGGER_STEP_MS) : 0;
|
|
199
|
+
const attributes = {
|
|
200
|
+
[ANIMATION_TRIGGER_ATTR]: trigger
|
|
201
|
+
};
|
|
202
|
+
if (repeat) attributes[ANIMATION_REPEAT_ATTR] = '1';
|
|
203
|
+
const style = {
|
|
204
|
+
[ANIMATION_DURATION_VAR]: `${durationMs}ms`,
|
|
205
|
+
[ANIMATION_DELAY_VAR]: `${delayMs}ms`
|
|
206
|
+
};
|
|
207
|
+
// Written only for a stagger host, so a plain animated element's inline
|
|
208
|
+
// style is byte for byte what it was before this shipped.
|
|
209
|
+
if (stagger) style[ANIMATION_STAGGER_STEP_VAR] = `${staggerStepMs}ms`;
|
|
210
|
+
return {
|
|
211
|
+
preset: preset,
|
|
212
|
+
trigger,
|
|
213
|
+
ease,
|
|
214
|
+
durationMs,
|
|
215
|
+
delayMs,
|
|
216
|
+
repeat,
|
|
217
|
+
stagger,
|
|
218
|
+
staggerStepMs,
|
|
219
|
+
className: `${stagger ? ANIMATION_GROUP_CLASS : ANIMATION_CLASS} ${ANIMATION_PRESET_CLASS_PREFIX}${preset} ${ANIMATION_EASE_CLASS_PREFIX}${ease}`,
|
|
220
|
+
attributes,
|
|
221
|
+
style
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* True when a node's props ask for a real animation. Cheap enough to run over
|
|
226
|
+
* every node in a screen's flat node map, which is how the tenant decides
|
|
227
|
+
* whether to ship the stylesheet at all.
|
|
228
|
+
*/ export function nodePropsAnimate(props) {
|
|
229
|
+
const preset = props == null ? void 0 : props[NODE_ANIMATION_PROP];
|
|
230
|
+
return typeof preset === 'string' && preset !== ANIMATION_NONE && ANIMATION_PRESETS.includes(preset);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
//# sourceMappingURL=element-animation.js.map
|