Files
2026-08-11 00:10:12 +08:00

484 lines
24 KiB
JavaScript

export const FRAMEWORKS = Object.freeze(["react", "vue", "angular"]);
export const GALLERY_FAMILIES = Object.freeze([
"gallery-marketing",
"gallery-commerce",
"gallery-editorial",
"gallery-workspaces",
"gallery-operations",
"gallery-community",
"gallery-service-portals",
]);
export const ADVANCED_PLATFORM_FAMILIES = Object.freeze([
"parser-document-boundaries",
"dom-observer-reactions",
"form-validation-association",
"worker-messaging-boundaries",
"history-navigation-boundaries",
"streams-encoding-boundaries",
"url-file-binary-boundaries",
"event-shadow-focus-boundaries",
"service-worker-cache-boundaries",
"cors-credentials-boundaries",
"custom-elements-form-boundaries",
"storage-lifecycle-boundaries",
"script-module-lifecycle",
"realtime-transport-boundaries",
]);
export const FAMILY_CASES = Object.freeze({
"text-and-attributes": [
["interpolation-card", "Interpolation card"],
["escaped-markup", "Escaped markup and entities"],
["boolean-attributes", "Boolean attribute projection"],
["aria-dataset", "ARIA and data attributes"],
["class-toggle", "Class token update"],
["inline-style-map", "Inline style map update"],
["unicode-content", "Unicode and bidi content"],
["nullable-values", "Null and missing values"],
["metadata-panel", "Metadata definition panel"],
["rich-article-header", "Rich article header"],
],
structure: [
["conditional-empty", "Conditional empty branch"],
["alternate-branch", "Alternate branch replacement"],
["nested-fragments", "Nested fragments"],
["template-like-content", "Template-like content"],
["comment-anchor", "Comment anchor projection"],
["details-summary", "Details and summary structure"],
["definition-outline", "Definition list outline"],
["semantic-article", "Semantic article regions"],
["deep-nesting", "Deep deterministic nesting"],
["document-outline", "Large document outline"],
],
collections: [
["basic-keyed-list", "Basic keyed list"],
["keyed-reorder", "Keyed list reorder"],
["keyed-prepend", "Keyed list prepend"],
["filtered-list", "Filtered list"],
["grouped-list", "Grouped list"],
["nested-tree", "Nested tree"],
["table-rows", "Dynamic table rows"],
["card-grid", "Card grid"],
["activity-feed", "Activity feed"],
["large-inventory", "Large inventory table"],
],
"state-and-batching": [
["counter-transition", "Counter transition"],
["batched-increments", "Batched increments"],
["derived-total", "Derived total"],
["toggle-state", "Toggle state"],
["reducer-steps", "Reducer steps"],
["linked-fields", "Linked derived fields"],
["queued-updates", "Queued state updates"],
["memo-summary", "Memoized summary"],
["state-machine", "State machine projection"],
["metrics-dashboard", "Metrics state dashboard"],
],
events: [
["click-update", "Click update"],
["bubble-order", "Event bubble order"],
["stop-propagation", "Stop propagation"],
["text-input", "Text input event"],
["change-event", "Change event"],
["form-submit", "Form submit event"],
["keyboard-event", "Keyboard event"],
["component-output", "Component output"],
["multiple-handlers", "Multiple event handlers"],
["command-palette", "Command palette interactions"],
],
forms: [
["controlled-text", "Controlled text field"],
["textarea-model", "Textarea model"],
["checkbox-group", "Checkbox group"],
["radio-group", "Radio group"],
["single-select", "Single select"],
["multiple-select", "Multiple select"],
["disabled-readonly", "Disabled and readonly controls"],
["validation-projection", "Validation state projection"],
["fieldset-editor", "Fieldset editor"],
["checkout-form", "Checkout form"],
],
components: [
["props-input", "Props and input"],
["nested-children", "Nested children"],
["context-provide", "Context and provide"],
["slots-render-props", "Slots and render props"],
["dynamic-component", "Dynamic component"],
["recursive-tree", "Recursive component tree"],
["portal-teleport", "Portal and teleport"],
["compound-components", "Compound components"],
["tab-system", "Tab component system"],
["application-shell", "Application component shell"],
],
"lifecycle-and-async": [
["mounted-mutation", "Mounted mutation"],
["effect-watch", "Effect and watch update"],
["microtask-update", "Microtask update"],
["promise-chain", "Promise chain"],
["timer-zero", "Zero-delay timer"],
["async-data", "Async data projection"],
["repeated-effects", "Repeated effects"],
["child-unmount", "Child unmount cleanup"],
["deferred-panel", "Deferred panel"],
["async-timeline", "Async timeline"],
],
"app-composition": [
["header-navigation", "Header navigation"],
["sidebar-layout", "Sidebar layout"],
["statistics-grid", "Statistics grid"],
["searchable-table", "Searchable table"],
["pagination-view", "Pagination view"],
["filter-chips", "Filter chip view"],
["profile-page", "Profile page"],
["notification-center", "Notification center"],
["settings-page", "Settings page"],
["admin-console", "Admin console"],
],
"complex-products": [
["operations-dashboard", "Operations dashboard"],
["commerce-catalog", "Commerce catalog"],
["kanban-board", "Kanban board"],
["mail-client", "Mail client"],
["team-chat", "Team chat"],
["documentation-site", "Documentation site"],
["booking-console", "Booking console"],
["issue-tracker", "Issue tracker"],
["analytics-workspace", "Analytics workspace"],
["invoice-editor", "Invoice editor"],
],
"web-platform-integration": [
["custom-element-shadow-upgrade", "Custom element shadow upgrade"],
["nested-shadow-slot-reassignment", "Nested shadow slot reassignment"],
["iframe-srcdoc-adoption", "Iframe srcdoc cross-document adoption"],
["iframe-document-write", "Iframe document.write parser pipeline"],
["storage-cookie-roundtrip", "Storage and cookie roundtrip"],
["fetch-xhr-dom-merge", "Fetch and XHR DOM merge"],
["mutation-observer-fragment-batch", "MutationObserver fragment batch"],
["range-treewalker-rewrite", "Range and TreeWalker rewrite"],
["formdata-searchparams-pipeline", "FormData and URLSearchParams pipeline"],
["shadow-event-abort-pipeline", "Shadow event and AbortSignal pipeline"],
],
"browsing-context-boundaries": [
["cross-origin-messagechannel", "Cross-origin MessageChannel handoff"],
["cross-origin-frame-renavigation", "Cross-origin frame renavigation"],
["same-to-cross-origin-transition", "Same-origin to cross-origin transition"],
["nested-cross-origin-frame-chain", "Nested cross-origin frame chain"],
["sandboxed-opaque-origin-frame", "Sandboxed opaque-origin frame"],
["iframe-srcdoc-realm-replacement", "Iframe srcdoc realm replacement"],
["custom-element-adopt-across-documents", "Custom element adoption across documents"],
["detached-custom-element-upgrade", "Detached custom element upgrade"],
["custom-element-reconnect-shadow-slot", "Custom element reconnect and shadow slot"],
["iframe-detach-recreate-context", "Iframe detach and context recreation"],
],
"network-storage-boundaries": [
["redirect-method-chain", "Redirect method and body transition"],
["streamed-response-clone", "Streamed response clone and tee"],
["abort-gated-response", "Abort a gated network response"],
["xhr-lifecycle-headers", "XHR lifecycle and response headers"],
["cache-storage-roundtrip", "CacheStorage network roundtrip"],
["indexeddb-versioned-cursor", "IndexedDB version and cursor transaction"],
["storage-event-multiframe", "Multi-frame storage event delivery"],
["cookie-path-http-only", "Cookie path and HttpOnly boundaries"],
["broadcastchannel-realm-clone", "BroadcastChannel realm structured clone"],
["blob-url-stream-revoke", "Blob URL stream and revocation"],
],
"parser-document-boundaries": [
["domparser-html-template", "DOMParser HTML and template content"],
["domparser-xml-errors", "DOMParser XML namespaces and parser errors"],
["contextual-fragment-table", "Contextual fragment table parsing"],
["document-fragment-adopt-import", "Document fragment adopt and import"],
["range-extract-surround", "Range extract clone and surround"],
["iterator-mutation-filter", "Iterator and walker mutation filtering"],
["text-split-normalize", "Text split replace and normalize"],
["xmlserializer-namespaces", "XMLSerializer namespace roundtrip"],
["insert-adjacent-parser", "Insert-adjacent parser positions"],
["create-html-document-base", "Detached HTML document base resolution"],
],
"dom-observer-reactions": [
["mutation-subtree-old-values", "Mutation subtree and old values"],
["take-records-disconnect", "Mutation takeRecords and disconnect"],
["fragment-reparent-records", "Fragment and reparent mutation records"],
["observer-reentrant-microtasks", "Reentrant observer microtask delivery"],
["custom-element-upgrade-reactions", "Custom element upgrade reactions"],
["custom-element-adopt-reactions", "Custom element adoption reactions"],
["shadow-slotchange-assignment", "Shadow slotchange and assignment"],
["shadow-observer-boundary", "Shadow mutation observer boundary"],
["event-microtask-mutation-order", "Event microtask mutation ordering"],
["replace-normalize-records", "Replace normalize mutation records"],
],
"form-validation-association": [
["required-pattern-validity", "Required and pattern validity transitions"],
["number-range-step-validity", "Number range and step validity"],
["custom-validity-reset", "Custom validity and form reset"],
["disabled-fieldset-legend", "Disabled fieldset legend exemption"],
["dynamic-form-owner", "Dynamic explicit form ownership"],
["request-submit-submitter", "Request submit and active submitter"],
["formdata-successful-controls", "FormData successful controls"],
["radio-group-validity", "Radio group validity and membership"],
["select-label-association", "Select validity and label association"],
["datalist-association", "Dynamic datalist association"],
],
"worker-messaging-boundaries": [
["dedicated-event-order", "Dedicated worker event ordering"],
["structured-clone-rich-values", "Worker rich structured clone values"],
["arraybuffer-transfer-roundtrip", "ArrayBuffer transfer round trip"],
["messageport-transfer-pipeline", "MessagePort transfer pipeline"],
["classic-importscripts-stack", "Classic worker importScripts stack"],
["module-worker-graph", "Module worker static and dynamic graph"],
["worker-fetch-stream", "Worker fetch stream consumption"],
["shared-worker-multi-port", "SharedWorker multiple client ports"],
["broadcast-channel-bridge", "Worker BroadcastChannel bridge"],
["terminate-and-replace", "Dedicated worker terminate and replacement"],
],
"history-navigation-boundaries": [
["push-replace-state-clone", "Push and replace state clone boundaries"],
["back-forward-event-order", "Back and forward event ordering"],
["go-multi-entry-traversal", "Multi-entry history.go traversal"],
["fragment-anchor-target", "Fragment anchor and target transitions"],
["state-clone-security-errors", "History state clone and URL security errors"],
["scroll-restoration-traversal", "Scroll restoration across traversal"],
["navigation-current-entry-state", "Navigation current entry state boundaries"],
["navigation-intercept-lifecycle", "Intercepted same-document navigation lifecycle"],
["navigation-traverse-promises", "Navigation traversal promises and events"],
["child-context-history", "Child browsing context history isolation"],
],
"streams-encoding-boundaries": [
["readable-controller-pull", "Readable stream controller and pull lifecycle"],
["readable-cancel-reason", "Readable stream cancellation reason"],
["tee-branch-consumption", "Tee branch consumption and cancellation"],
["transform-pipe-backpressure", "Transform pipe and backpressure"],
["writable-close-abort", "Writable close and abort lifecycle"],
["decoder-split-codepoints", "Streaming decoder split code points"],
["decoder-fatal-recovery", "Fatal decoder error and recovery"],
["encoding-stream-pipeline", "Text encoding stream pipeline"],
["byte-stream-byob", "Readable byte stream BYOB reads"],
["blob-response-stream", "Blob and Response stream consumption"],
],
"url-file-binary-boundaries": [
["url-resolution-mutation", "URL resolution and component mutation"],
["searchparams-live-binding", "URLSearchParams live URL binding"],
["searchparams-iterator-mutation", "URLSearchParams iterator mutation"],
["blob-unicode-slice", "Blob Unicode bytes and slicing"],
["file-metadata-formdata", "File metadata and FormData identity"],
["filereader-event-sequence", "FileReader event and result sequence"],
["filereader-abort-reuse", "FileReader abort and reuse lifecycle"],
["structured-clone-binary-transfer", "Structured clone binary transfer and aliasing"],
["data-url-fetch-binary", "Data URL text and binary fetch"],
["response-binary-clone", "Binary Response clone consumption"],
],
"event-shadow-focus-boundaries": [
["capture-bubble-order", "Capture and bubble event order"],
["propagation-stop-boundaries", "Propagation stop boundaries"],
["listener-options-signal", "Listener once passive and AbortSignal options"],
["shadow-composed-retarget", "Shadow composed event retargeting"],
["closed-shadow-path", "Closed shadow composed path filtering"],
["slot-reassignment-path", "Slot reassignment and event path"],
["focus-blur-order", "Focus blur and related target order"],
["shadow-focus-retarget", "Shadow focus active element retargeting"],
["listener-mutation-dispatch", "Listener mutation during dispatch"],
["custom-event-redispatch", "CustomEvent cancelation and redispatch"],
],
"service-worker-cache-boundaries": [
["registration-ready-controller", "Service worker registration, ready, and controller"],
["synthetic-fetch-metadata", "Service worker synthetic fetch metadata"],
["precache-fetch-roundtrip", "Service worker precache and message cache roundtrip"],
["cache-storage-lifecycle", "Service worker CacheStorage lifecycle"],
["messagechannel-binary-transfer", "Service worker MessageChannel binary transfer"],
["clients-claim-inspection", "Service worker clients claim and inspection"],
["streamed-response-clone", "Service worker streamed response cloning"],
["fallback-and-redirect", "Service worker network fallback and redirect"],
["unregister-controlled-client", "Service worker unregister controlled client boundary"],
["updatefound-controller-replacement", "Service worker update and controller replacement"],
],
"cors-credentials-boundaries": [
["simple-allow-deny", "Simple CORS allow and deny"],
["exposed-header-filtering", "CORS exposed response header filtering"],
["credentials-response-guard", "Credentialed CORS response guard"],
["wildcard-credentials-rejected", "CORS wildcard credential rejection"],
["allowed-preflight-put", "Allowed CORS preflight PUT"],
["denied-preflight-method", "Denied CORS preflight method"],
["denied-preflight-header", "Denied CORS preflight header"],
["xhr-preflight-lifecycle", "CORS XHR preflight lifecycle"],
["redirect-after-preflight", "CORS redirect after preflight"],
["opaque-and-request-metadata", "Opaque response and Fetch Metadata"],
],
"custom-elements-form-boundaries": [
["form-value-string-transition", "Form-associated string value transition"],
["formdata-multi-value-transition", "Form-associated multi-value FormData transition"],
["dynamic-form-owner-reassociation", "Dynamic custom-element form owner reassociation"],
["disabled-fieldset-legend-transition", "Disabled fieldset and first-legend custom element"],
["internals-validity-submit-transition", "ElementInternals validity and submit transition"],
["reset-callback-form-state", "Form reset callback and custom state"],
["label-association-retarget", "Custom-element label association retargeting"],
["delayed-upgrade-association", "Delayed custom-element upgrade and form association"],
["adopt-reconnect-lifecycle", "Custom-element adopt and reconnect lifecycle"],
["custom-state-shadow-upgrade", "Custom state shadow-tree upgrade"],
],
"storage-lifecycle-boundaries": [
["indexeddb-upgrade-abort-rollback", "IndexedDB aborted upgrade rollback"],
["indexeddb-transaction-queue-rollback", "IndexedDB transaction queue and rollback"],
["indexeddb-blocked-version-delete", "IndexedDB blocked version and deletion lifecycle"],
["indexeddb-index-cursor-rollback", "IndexedDB indexes across rollback and commit"],
["cache-delete-live-handle", "Cache deletion with a live Cache handle"],
["cache-query-options-lifecycle", "Cache query options and entry deletion"],
["local-storage-cross-realm-events", "Cross-realm localStorage event delivery"],
["session-storage-frame-replacement", "Session storage across frame replacement"],
["opfs-write-truncate-remove", "OPFS write, truncate, remove, and recreate"],
["opfs-handle-capability-clone", "OPFS handle clone and stale capability lifecycle"],
],
"script-module-lifecycle": [
["parser-blocking-defer-order", "Parser, defer, load, and dynamic script ordering"],
["dynamic-classic-sequential-queue", "Dynamic classic script sequential queue"],
["inert-type-clone-execution", "Inert script mutation, cloning, and reinsertion"],
["document-write-nested-scripts", "Nested document.write script execution"],
["module-static-graph-tla", "Static module graph and top-level await"],
["dynamic-import-cache-query", "Dynamic import cache and query identity"],
["import-map-bare-specifier", "Import-map static and dynamic bare specifiers"],
["module-failure-recovery", "Module graph failure and independent recovery"],
["document-open-realm-replacement", "Document.open script realm replacement"],
["current-script-cross-document-move", "CurrentScript and evaluated cross-document move"],
],
"realtime-transport-boundaries": [
["websocket-text-order", "WebSocket text message ordering"],
["websocket-binary-arraybuffer", "WebSocket binary ArrayBuffer frames"],
["websocket-fragmented-binary", "WebSocket fragmented Blob and ArrayBuffer messages"],
["websocket-subprotocol-origin", "WebSocket subprotocol and Origin metadata"],
["websocket-close-handshake", "WebSocket client and server close handshakes"],
["websocket-iframe-teardown", "WebSocket iframe realm teardown"],
["eventsource-multiline-custom", "EventSource multiline custom events"],
["eventsource-reconnect-last-id", "EventSource reconnect and Last-Event-ID"],
["eventsource-close-ready-state", "EventSource close and readyState lifecycle"],
["websocket-eventsource-coordination", "Coordinated WebSocket and EventSource lifecycle"],
],
"gallery-marketing": [
["ai-agent-launch", "AI agent product launch"],
["climate-platform-story", "Climate platform story"],
["design-studio-portfolio", "Design studio portfolio"],
["architecture-case-study", "Architecture case study"],
["nonprofit-impact-report", "Nonprofit impact report"],
["developer-cloud-platform", "Developer cloud platform"],
["security-enterprise-suite", "Security enterprise suite"],
["product-comparison-hub", "Product comparison hub"],
["conference-event-launch", "Conference event launch"],
["museum-exhibition-story", "Museum exhibition story"],
],
"gallery-commerce": [
["fashion-marketplace", "Fashion marketplace"],
["furniture-configurator", "Furniture configurator"],
["grocery-delivery", "Grocery delivery"],
["electronics-comparison", "Electronics comparison"],
["beauty-subscription", "Beauty subscription"],
["ticket-resale-market", "Ticket resale market"],
["digital-template-store", "Digital template store"],
["restaurant-ordering", "Restaurant ordering"],
["wholesale-procurement", "Wholesale procurement"],
["live-auction-lots", "Live auction lots"],
],
"gallery-editorial": [
["breaking-news-desk", "Breaking news desk"],
["culture-magazine", "Culture magazine"],
["research-journal", "Research journal"],
["recipe-publication", "Recipe publication"],
["sports-live-blog", "Sports live blog"],
["podcast-network", "Podcast network"],
["photographic-essay", "Photographic essay"],
["product-changelog", "Product changelog"],
["local-city-guide", "Local city guide"],
["newsletter-archive", "Newsletter archive"],
],
"gallery-workspaces": [
["crm-pipeline", "CRM pipeline"],
["project-command-center", "Project command center"],
["collaborative-documents", "Collaborative documents"],
["support-inbox", "Support inbox"],
["developer-observability", "Developer observability"],
["feature-flag-console", "Feature flag console"],
["design-token-manager", "Design token manager"],
["applicant-tracking", "Applicant tracking"],
["inventory-planning", "Inventory planning"],
["automation-flow-builder", "Automation flow builder"],
],
"gallery-operations": [
["executive-analytics", "Executive analytics"],
["incident-command", "Incident command"],
["network-topology", "Network topology"],
["logistics-control-tower", "Logistics control tower"],
["energy-grid-monitor", "Energy grid monitor"],
["fraud-review-queue", "Fraud review queue"],
["experiment-analysis", "Experiment analysis"],
["compliance-audit", "Compliance audit"],
["cloud-cost-explorer", "Cloud cost explorer"],
["database-query-console", "Database query console"],
],
"gallery-community": [
["creator-profile-feed", "Creator profile feed"],
["team-community", "Team community"],
["conference-schedule", "Conference schedule"],
["moderation-queue", "Moderation queue"],
["learning-cohort", "Learning cohort"],
["volunteer-network", "Volunteer network"],
["neighborhood-forum", "Neighborhood forum"],
["gaming-guild", "Gaming guild"],
["professional-directory", "Professional directory"],
["live-stream-chat", "Live stream chat"],
],
"gallery-service-portals": [
["flight-search", "Flight search portal"],
["hotel-booking", "Hotel booking portal"],
["digital-banking", "Digital banking portal"],
["insurance-claims", "Insurance claims portal"],
["patient-care", "Patient care portal"],
["course-enrollment", "Course enrollment portal"],
["property-search", "Property search portal"],
["energy-account", "Energy account portal"],
["public-benefits", "Public benefits portal"],
["payroll-benefits", "Payroll and benefits portal"],
],
});
export const FAMILIES = Object.freeze(Object.keys(FAMILY_CASES));
function complexityFor(family, index) {
if (
family === "web-platform-integration" ||
family === "browsing-context-boundaries" ||
family === "network-storage-boundaries" ||
ADVANCED_PLATFORM_FAMILIES.includes(family) ||
GALLERY_FAMILIES.includes(family)
) {
return "complex";
}
if (index < 4) {
return "simple";
}
if (index < 8) {
return "medium";
}
return "complex";
}
export function buildCatalog() {
const cases = [];
for (const framework of FRAMEWORKS) {
FAMILIES.forEach((family, familyIndex) => {
FAMILY_CASES[family].forEach(([slug, title], variant) => {
cases.push({
id: `${framework}/${family}/${slug}`,
framework,
family,
complexity: complexityFor(family, variant),
slug,
title,
variant,
seed: familyIndex * 17 + variant * 7 + 11,
size: 4 + variant * 3,
path: `/cases/${framework}/${family}/${slug}/index.html`,
});
});
});
}
return cases;
}