@fictjs/runtime 0.16.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.cjs +9 -9
- package/dist/advanced.d.cts +3 -3
- package/dist/advanced.d.ts +3 -3
- package/dist/advanced.js +4 -4
- package/dist/{binding-CQUGLLBI.d.ts → binding-BfzY9rae.d.ts} +2 -2
- package/dist/{binding-BlABuUiG.d.cts → binding-CDR2ERoq.d.cts} +2 -2
- package/dist/{chunk-CBRGOLTR.cjs → chunk-2J4INHDT.cjs} +40 -40
- package/dist/{chunk-CBRGOLTR.cjs.map → chunk-2J4INHDT.cjs.map} +1 -1
- package/dist/{chunk-BADX4WTQ.cjs → chunk-CKKZDUHM.cjs} +21 -18
- package/dist/chunk-CKKZDUHM.cjs.map +1 -0
- package/dist/{chunk-ZWQLXWSV.js → chunk-DHRRJJ6W.js} +8 -5
- package/dist/chunk-DHRRJJ6W.js.map +1 -0
- package/dist/{chunk-4P4DYWLQ.js → chunk-LFLFSJFU.js} +3 -3
- package/dist/{chunk-WJMZ7X46.cjs → chunk-NBDEMBBX.cjs} +47 -85
- package/dist/chunk-NBDEMBBX.cjs.map +1 -0
- package/dist/{chunk-MAHWGB55.js → chunk-OKPQWORE.js} +47 -85
- package/dist/chunk-OKPQWORE.js.map +1 -0
- package/dist/{chunk-RK2WSQYL.js → chunk-OLHZBAIF.js} +3 -3
- package/dist/{chunk-ZJZ6LMDN.js → chunk-R2HYEOP7.js} +470 -172
- package/dist/chunk-R2HYEOP7.js.map +1 -0
- package/dist/{chunk-AR2T7JEX.cjs → chunk-UG2IFQOY.cjs} +650 -352
- package/dist/chunk-UG2IFQOY.cjs.map +1 -0
- package/dist/{chunk-ECNK25S4.cjs → chunk-VP2WC7X3.cjs} +8 -8
- package/dist/{chunk-ECNK25S4.cjs.map → chunk-VP2WC7X3.cjs.map} +1 -1
- package/dist/{devtools-DWIZRe7L.d.cts → devtools-BwkkQ6DN.d.cts} +1 -1
- package/dist/{devtools-DNnnDGu1.d.ts → devtools-CK3SVU_w.d.ts} +1 -1
- package/dist/index.cjs +55 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.dev.js +260 -156
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +16 -3
- package/dist/index.js.map +1 -1
- package/dist/internal-list.cjs +4 -4
- package/dist/internal-list.js +3 -3
- package/dist/internal.cjs +5 -5
- package/dist/internal.d.cts +4 -4
- package/dist/internal.d.ts +4 -4
- package/dist/internal.js +4 -4
- package/dist/jsx-dev-runtime.cjs.map +1 -1
- package/dist/jsx-dev-runtime.d.cts +46 -0
- package/dist/jsx-dev-runtime.d.ts +46 -0
- package/dist/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx-runtime.cjs.map +1 -1
- package/dist/jsx-runtime.d.cts +46 -0
- package/dist/jsx-runtime.d.ts +46 -0
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/loader.cjs +143 -26
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +1 -1
- package/dist/loader.d.ts +1 -1
- package/dist/loader.js +122 -5
- package/dist/loader.js.map +1 -1
- package/dist/{props-DabFQwLR.d.ts → props-CFoQ471Y.d.ts} +47 -1
- package/dist/{props-tImUZAty.d.cts → props-D4tK8Gn0.d.cts} +47 -1
- package/dist/{resume-C5IKAIdh.d.ts → resume-C166aAVg.d.ts} +2 -2
- package/dist/{resume-DPZxmA95.d.cts → resume-C20cRVj9.d.cts} +2 -2
- package/dist/{scope-gpOMWTlf.d.ts → scope-BFzD_7hx.d.ts} +1 -1
- package/dist/{scope-GwC4DJ50.d.cts → scope-Ck3mTQVS.d.cts} +1 -1
- package/package.json +1 -1
- package/src/binding.ts +561 -166
- package/src/context.ts +8 -1
- package/src/dom.ts +26 -44
- package/src/effect.ts +9 -12
- package/src/error-boundary.ts +8 -0
- package/src/hydration.ts +25 -6
- package/src/jsx.ts +46 -0
- package/src/lifecycle.ts +31 -79
- package/src/loader.ts +153 -4
- package/src/resume.ts +5 -5
- package/src/signal.ts +4 -1
- package/src/suspense.ts +8 -0
- package/dist/chunk-AR2T7JEX.cjs.map +0 -1
- package/dist/chunk-BADX4WTQ.cjs.map +0 -1
- package/dist/chunk-MAHWGB55.js.map +0 -1
- package/dist/chunk-WJMZ7X46.cjs.map +0 -1
- package/dist/chunk-ZJZ6LMDN.js.map +0 -1
- package/dist/chunk-ZWQLXWSV.js.map +0 -1
- /package/dist/{chunk-4P4DYWLQ.js.map → chunk-LFLFSJFU.js.map} +0 -0
- /package/dist/{chunk-RK2WSQYL.js.map → chunk-OLHZBAIF.js.map} +0 -0
package/dist/jsx-runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/jsx.ts"],"sourcesContent":["import type { FictNode } from './types'\n\nexport const Fragment = Symbol('Fragment')\n\nexport function jsx(\n type: string | typeof Fragment | ((props: Record<string, unknown>) => FictNode),\n props: Record<string, unknown>,\n key?: string,\n): FictNode {\n return { type, props, key }\n}\n\nexport const jsxs = jsx\nexport const jsxDEV = jsx\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace JSX {\n export type Element = FictNode\n\n export interface IntrinsicElements {\n // Document structure\n html: HTMLAttributes<HTMLHtmlElement>\n head: HTMLAttributes<HTMLHeadElement>\n body: HTMLAttributes<HTMLBodyElement>\n title: HTMLAttributes<HTMLTitleElement>\n meta: MetaHTMLAttributes<HTMLMetaElement>\n link: LinkHTMLAttributes<HTMLLinkElement>\n style: StyleHTMLAttributes<HTMLStyleElement>\n script: ScriptHTMLAttributes<HTMLScriptElement>\n noscript: HTMLAttributes<HTMLElement>\n\n // Layout & Semantic\n div: HTMLAttributes<HTMLDivElement>\n span: HTMLAttributes<HTMLSpanElement>\n main: HTMLAttributes<HTMLElement>\n header: HTMLAttributes<HTMLElement>\n footer: HTMLAttributes<HTMLElement>\n section: HTMLAttributes<HTMLElement>\n article: HTMLAttributes<HTMLElement>\n aside: HTMLAttributes<HTMLElement>\n nav: HTMLAttributes<HTMLElement>\n address: HTMLAttributes<HTMLElement>\n\n // Headings\n h1: HTMLAttributes<HTMLHeadingElement>\n h2: HTMLAttributes<HTMLHeadingElement>\n h3: HTMLAttributes<HTMLHeadingElement>\n h4: HTMLAttributes<HTMLHeadingElement>\n h5: HTMLAttributes<HTMLHeadingElement>\n h6: HTMLAttributes<HTMLHeadingElement>\n hgroup: HTMLAttributes<HTMLElement>\n\n // Text content\n p: HTMLAttributes<HTMLParagraphElement>\n blockquote: BlockquoteHTMLAttributes<HTMLQuoteElement>\n pre: HTMLAttributes<HTMLPreElement>\n figure: HTMLAttributes<HTMLElement>\n figcaption: HTMLAttributes<HTMLElement>\n hr: HTMLAttributes<HTMLHRElement>\n br: HTMLAttributes<HTMLBRElement>\n wbr: HTMLAttributes<HTMLElement>\n\n // Inline text semantics\n a: AnchorHTMLAttributes<HTMLAnchorElement>\n abbr: HTMLAttributes<HTMLElement>\n b: HTMLAttributes<HTMLElement>\n bdi: HTMLAttributes<HTMLElement>\n bdo: HTMLAttributes<HTMLElement>\n cite: HTMLAttributes<HTMLElement>\n code: HTMLAttributes<HTMLElement>\n data: DataHTMLAttributes<HTMLDataElement>\n dfn: HTMLAttributes<HTMLElement>\n em: HTMLAttributes<HTMLElement>\n i: HTMLAttributes<HTMLElement>\n kbd: HTMLAttributes<HTMLElement>\n mark: HTMLAttributes<HTMLElement>\n q: QuoteHTMLAttributes<HTMLQuoteElement>\n rp: HTMLAttributes<HTMLElement>\n rt: HTMLAttributes<HTMLElement>\n ruby: HTMLAttributes<HTMLElement>\n s: HTMLAttributes<HTMLElement>\n samp: HTMLAttributes<HTMLElement>\n small: HTMLAttributes<HTMLElement>\n strong: HTMLAttributes<HTMLElement>\n sub: HTMLAttributes<HTMLElement>\n sup: HTMLAttributes<HTMLElement>\n time: TimeHTMLAttributes<HTMLTimeElement>\n u: HTMLAttributes<HTMLElement>\n var: HTMLAttributes<HTMLElement>\n\n // Lists\n ul: HTMLAttributes<HTMLUListElement>\n ol: OlHTMLAttributes<HTMLOListElement>\n li: LiHTMLAttributes<HTMLLIElement>\n dl: HTMLAttributes<HTMLDListElement>\n dt: HTMLAttributes<HTMLElement>\n dd: HTMLAttributes<HTMLElement>\n menu: HTMLAttributes<HTMLMenuElement>\n\n // Tables\n table: TableHTMLAttributes<HTMLTableElement>\n caption: HTMLAttributes<HTMLTableCaptionElement>\n colgroup: ColgroupHTMLAttributes<HTMLTableColElement>\n col: ColHTMLAttributes<HTMLTableColElement>\n thead: HTMLAttributes<HTMLTableSectionElement>\n tbody: HTMLAttributes<HTMLTableSectionElement>\n tfoot: HTMLAttributes<HTMLTableSectionElement>\n tr: HTMLAttributes<HTMLTableRowElement>\n th: ThHTMLAttributes<HTMLTableCellElement>\n td: TdHTMLAttributes<HTMLTableCellElement>\n\n // Forms\n form: FormHTMLAttributes<HTMLFormElement>\n fieldset: FieldsetHTMLAttributes<HTMLFieldSetElement>\n legend: HTMLAttributes<HTMLLegendElement>\n label: LabelHTMLAttributes<HTMLLabelElement>\n input: InputHTMLAttributes<HTMLInputElement>\n button: ButtonHTMLAttributes<HTMLButtonElement>\n select: SelectHTMLAttributes<HTMLSelectElement>\n datalist: HTMLAttributes<HTMLDataListElement>\n optgroup: OptgroupHTMLAttributes<HTMLOptGroupElement>\n option: OptionHTMLAttributes<HTMLOptionElement>\n textarea: TextareaHTMLAttributes<HTMLTextAreaElement>\n output: OutputHTMLAttributes<HTMLOutputElement>\n progress: ProgressHTMLAttributes<HTMLProgressElement>\n meter: MeterHTMLAttributes<HTMLMeterElement>\n\n // Interactive\n details: DetailsHTMLAttributes<HTMLDetailsElement>\n summary: HTMLAttributes<HTMLElement>\n dialog: DialogHTMLAttributes<HTMLDialogElement>\n\n // Media\n img: ImgHTMLAttributes<HTMLImageElement>\n picture: HTMLAttributes<HTMLPictureElement>\n source: SourceHTMLAttributes<HTMLSourceElement>\n audio: AudioVideoHTMLAttributes<HTMLAudioElement>\n video: AudioVideoHTMLAttributes<HTMLVideoElement>\n track: TrackHTMLAttributes<HTMLTrackElement>\n map: MapHTMLAttributes<HTMLMapElement>\n area: AreaHTMLAttributes<HTMLAreaElement>\n\n // Embedded content\n iframe: IframeHTMLAttributes<HTMLIFrameElement>\n embed: EmbedHTMLAttributes<HTMLEmbedElement>\n object: ObjectHTMLAttributes<HTMLObjectElement>\n param: ParamHTMLAttributes<HTMLParamElement>\n canvas: CanvasHTMLAttributes<HTMLCanvasElement>\n\n // SVG (basic support)\n svg: SVGAttributes<SVGSVGElement>\n path: SVGAttributes<SVGPathElement>\n circle: SVGAttributes<SVGCircleElement>\n rect: SVGAttributes<SVGRectElement>\n line: SVGAttributes<SVGLineElement>\n polyline: SVGAttributes<SVGPolylineElement>\n polygon: SVGAttributes<SVGPolygonElement>\n ellipse: SVGAttributes<SVGEllipseElement>\n g: SVGAttributes<SVGGElement>\n defs: SVGAttributes<SVGDefsElement>\n use: SVGAttributes<SVGUseElement>\n text: SVGAttributes<SVGTextElement>\n tspan: SVGAttributes<SVGTSpanElement>\n\n // Web components / other\n template: HTMLAttributes<HTMLTemplateElement>\n slot: SlotHTMLAttributes<HTMLSlotElement>\n portal: HTMLAttributes<HTMLElement>\n }\n\n export interface ElementChildrenAttribute {\n children: unknown\n }\n}\n\n// ============================================================================\n// Base HTML Attributes\n// ============================================================================\n\ninterface HTMLAttributes<T> {\n // Children\n children?: FictNode | FictNode[]\n\n // JSX special attributes\n key?: string | number\n\n // Core attributes\n id?: string\n class?: string\n style?: string | Record<string, string | number>\n title?: string\n lang?: string\n dir?: 'ltr' | 'rtl' | 'auto'\n hidden?: boolean | 'hidden' | 'until-found'\n tabIndex?: number\n draggable?: boolean | 'true' | 'false'\n contentEditable?: boolean | 'true' | 'false' | 'inherit'\n spellCheck?: boolean | 'true' | 'false'\n translate?: 'yes' | 'no'\n inert?: boolean\n popover?: 'auto' | 'manual'\n\n // Experimental / newer\n autofocus?: boolean\n slot?: string\n accessKey?: string\n\n // Event handlers\n onClick?: (e: MouseEvent) => void\n onDblClick?: (e: MouseEvent) => void\n onMouseDown?: (e: MouseEvent) => void\n onMouseUp?: (e: MouseEvent) => void\n onMouseMove?: (e: MouseEvent) => void\n onMouseEnter?: (e: MouseEvent) => void\n onMouseLeave?: (e: MouseEvent) => void\n onMouseOver?: (e: MouseEvent) => void\n onMouseOut?: (e: MouseEvent) => void\n onContextMenu?: (e: MouseEvent) => void\n onInput?: (e: InputEvent) => void\n onChange?: (e: Event) => void\n onSubmit?: (e: SubmitEvent) => void\n onReset?: (e: Event) => void\n onKeyDown?: (e: KeyboardEvent) => void\n onKeyUp?: (e: KeyboardEvent) => void\n onKeyPress?: (e: KeyboardEvent) => void\n onFocus?: (e: FocusEvent) => void\n onBlur?: (e: FocusEvent) => void\n onScroll?: (e: Event) => void\n onWheel?: (e: WheelEvent) => void\n onLoad?: (e: Event) => void\n onError?: (e: Event) => void\n\n // Drag events\n onDrag?: (e: DragEvent) => void\n onDragStart?: (e: DragEvent) => void\n onDragEnd?: (e: DragEvent) => void\n onDragEnter?: (e: DragEvent) => void\n onDragLeave?: (e: DragEvent) => void\n onDragOver?: (e: DragEvent) => void\n onDrop?: (e: DragEvent) => void\n\n // Touch events\n onTouchStart?: (e: TouchEvent) => void\n onTouchMove?: (e: TouchEvent) => void\n onTouchEnd?: (e: TouchEvent) => void\n onTouchCancel?: (e: TouchEvent) => void\n\n // Animation events\n onAnimationStart?: (e: AnimationEvent) => void\n onAnimationEnd?: (e: AnimationEvent) => void\n onAnimationIteration?: (e: AnimationEvent) => void\n onTransitionEnd?: (e: TransitionEvent) => void\n\n // Pointer events\n onPointerDown?: (e: PointerEvent) => void\n onPointerUp?: (e: PointerEvent) => void\n onPointerMove?: (e: PointerEvent) => void\n onPointerEnter?: (e: PointerEvent) => void\n onPointerLeave?: (e: PointerEvent) => void\n onPointerOver?: (e: PointerEvent) => void\n onPointerOut?: (e: PointerEvent) => void\n onPointerCancel?: (e: PointerEvent) => void\n\n // Ref\n ref?: ((el: T | null) => void) | { current: T | null }\n\n // ARIA attributes (common ones)\n role?: string\n 'aria-hidden'?: boolean | 'true' | 'false'\n 'aria-label'?: string\n 'aria-labelledby'?: string\n 'aria-describedby'?: string\n 'aria-live'?: 'off' | 'polite' | 'assertive'\n 'aria-atomic'?: boolean | 'true' | 'false'\n 'aria-busy'?: boolean | 'true' | 'false'\n 'aria-current'?: boolean | 'true' | 'false' | 'page' | 'step' | 'location' | 'date' | 'time'\n 'aria-disabled'?: boolean | 'true' | 'false'\n 'aria-expanded'?: boolean | 'true' | 'false'\n 'aria-haspopup'?: boolean | 'true' | 'false' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'\n 'aria-pressed'?: boolean | 'true' | 'false' | 'mixed'\n 'aria-selected'?: boolean | 'true' | 'false'\n 'aria-checked'?: boolean | 'true' | 'false' | 'mixed'\n 'aria-controls'?: string\n 'aria-owns'?: string\n 'aria-activedescendant'?: string\n 'aria-valuemin'?: number\n 'aria-valuemax'?: number\n 'aria-valuenow'?: number\n 'aria-valuetext'?: string\n 'aria-orientation'?: 'horizontal' | 'vertical'\n 'aria-readonly'?: boolean | 'true' | 'false'\n 'aria-required'?: boolean | 'true' | 'false'\n 'aria-invalid'?: boolean | 'true' | 'false' | 'grammar' | 'spelling'\n 'aria-errormessage'?: string\n 'aria-modal'?: boolean | 'true' | 'false'\n 'aria-placeholder'?: string\n 'aria-sort'?: 'none' | 'ascending' | 'descending' | 'other'\n 'aria-colcount'?: number\n 'aria-colindex'?: number\n 'aria-colspan'?: number\n 'aria-rowcount'?: number\n 'aria-rowindex'?: number\n 'aria-rowspan'?: number\n 'aria-setsize'?: number\n 'aria-posinset'?: number\n 'aria-level'?: number\n 'aria-multiselectable'?: boolean | 'true' | 'false'\n 'aria-autocomplete'?: 'none' | 'inline' | 'list' | 'both'\n 'aria-details'?: string\n 'aria-keyshortcuts'?: string\n 'aria-roledescription'?: string\n\n // Data attributes via index signature\n [key: `data-${string}`]: string | number | boolean | undefined\n}\n\n// ============================================================================\n// Specialized Attribute Interfaces\n// ============================================================================\n\ninterface AnchorHTMLAttributes<T> extends HTMLAttributes<T> {\n href?: string\n target?: '_self' | '_blank' | '_parent' | '_top' | string\n rel?: string\n download?: boolean | string\n hreflang?: string\n type?: string\n referrerPolicy?: ReferrerPolicy\n ping?: string\n}\n\ninterface ButtonHTMLAttributes<T> extends HTMLAttributes<T> {\n type?: 'button' | 'submit' | 'reset'\n disabled?: boolean\n name?: string\n value?: string\n form?: string\n formAction?: string\n formEncType?: string\n formMethod?: string\n formNoValidate?: boolean\n formTarget?: string\n popovertarget?: string\n popovertargetaction?: 'show' | 'hide' | 'toggle'\n}\n\ninterface InputHTMLAttributes<T> extends HTMLAttributes<T> {\n type?: string\n value?: string | number | readonly string[]\n defaultValue?: string | number | readonly string[]\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n placeholder?: string\n name?: string\n form?: string\n required?: boolean\n readonly?: boolean\n multiple?: boolean\n min?: number | string\n max?: number | string\n minLength?: number\n maxLength?: number\n step?: number | string\n pattern?: string\n size?: number\n accept?: string\n capture?: boolean | 'user' | 'environment'\n list?: string\n autoComplete?: string\n autoCapitalize?: string\n inputMode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'\n enterKeyHint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send'\n height?: number | string\n width?: number | string\n alt?: string\n src?: string\n formAction?: string\n formEncType?: string\n formMethod?: string\n formNoValidate?: boolean\n formTarget?: string\n}\n\ninterface FormHTMLAttributes<T> extends HTMLAttributes<T> {\n action?: string\n method?: 'get' | 'post' | 'dialog'\n encType?: string\n target?: string\n name?: string\n noValidate?: boolean\n autoComplete?: 'on' | 'off'\n acceptCharset?: string\n}\n\ninterface ImgHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n alt?: string\n width?: number | string\n height?: number | string\n srcSet?: string\n sizes?: string\n loading?: 'eager' | 'lazy'\n decoding?: 'async' | 'auto' | 'sync'\n crossOrigin?: 'anonymous' | 'use-credentials'\n referrerPolicy?: ReferrerPolicy\n useMap?: string\n isMap?: boolean\n fetchPriority?: 'auto' | 'high' | 'low'\n}\n\ninterface TextareaHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string | number\n defaultValue?: string\n disabled?: boolean\n placeholder?: string\n name?: string\n form?: string\n required?: boolean\n readonly?: boolean\n rows?: number\n cols?: number\n minLength?: number\n maxLength?: number\n wrap?: 'hard' | 'soft' | 'off'\n autoComplete?: string\n}\n\ninterface SelectHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string | number | readonly string[]\n defaultValue?: string | number | readonly string[]\n disabled?: boolean\n name?: string\n form?: string\n required?: boolean\n multiple?: boolean\n size?: number\n autoComplete?: string\n}\n\ninterface OptionHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string | number\n disabled?: boolean\n selected?: boolean\n label?: string\n}\n\ninterface OptgroupHTMLAttributes<T> extends HTMLAttributes<T> {\n disabled?: boolean\n label?: string\n}\n\ninterface LabelHTMLAttributes<T> extends HTMLAttributes<T> {\n for?: string\n htmlFor?: string\n form?: string\n}\n\ninterface FieldsetHTMLAttributes<T> extends HTMLAttributes<T> {\n disabled?: boolean\n name?: string\n form?: string\n}\n\ninterface OutputHTMLAttributes<T> extends HTMLAttributes<T> {\n for?: string\n htmlFor?: string\n form?: string\n name?: string\n}\n\ninterface ProgressHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: number | string\n max?: number | string\n}\n\ninterface MeterHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: number | string\n min?: number | string\n max?: number | string\n low?: number | string\n high?: number | string\n optimum?: number | string\n}\n\n// Table elements\ninterface TableHTMLAttributes<T> extends HTMLAttributes<T> {\n cellPadding?: number | string\n cellSpacing?: number | string\n border?: number | string\n}\n\ninterface ThHTMLAttributes<T> extends HTMLAttributes<T> {\n colSpan?: number\n rowSpan?: number\n scope?: 'row' | 'col' | 'rowgroup' | 'colgroup'\n abbr?: string\n headers?: string\n}\n\ninterface TdHTMLAttributes<T> extends HTMLAttributes<T> {\n colSpan?: number\n rowSpan?: number\n headers?: string\n}\n\ninterface ColHTMLAttributes<T> extends HTMLAttributes<T> {\n span?: number\n}\n\ninterface ColgroupHTMLAttributes<T> extends HTMLAttributes<T> {\n span?: number\n}\n\n// List elements\ninterface OlHTMLAttributes<T> extends HTMLAttributes<T> {\n start?: number\n reversed?: boolean\n type?: '1' | 'a' | 'A' | 'i' | 'I'\n}\n\ninterface LiHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: number\n}\n\n// Media elements\ninterface AudioVideoHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n controls?: boolean\n autoPlay?: boolean\n loop?: boolean\n muted?: boolean\n preload?: 'none' | 'metadata' | 'auto'\n crossOrigin?: 'anonymous' | 'use-credentials'\n poster?: string // video only\n width?: number | string // video only\n height?: number | string // video only\n playsInline?: boolean\n disableRemotePlayback?: boolean\n onPlay?: (e: Event) => void\n onPause?: (e: Event) => void\n onEnded?: (e: Event) => void\n onTimeUpdate?: (e: Event) => void\n onVolumeChange?: (e: Event) => void\n onSeeking?: (e: Event) => void\n onSeeked?: (e: Event) => void\n onLoadedData?: (e: Event) => void\n onLoadedMetadata?: (e: Event) => void\n onCanPlay?: (e: Event) => void\n onCanPlayThrough?: (e: Event) => void\n onWaiting?: (e: Event) => void\n onPlaying?: (e: Event) => void\n onProgress?: (e: Event) => void\n onDurationChange?: (e: Event) => void\n onRateChange?: (e: Event) => void\n onStalled?: (e: Event) => void\n onSuspend?: (e: Event) => void\n onEmptied?: (e: Event) => void\n}\n\ninterface SourceHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n srcSet?: string\n sizes?: string\n type?: string\n media?: string\n width?: number | string\n height?: number | string\n}\n\ninterface TrackHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n srcLang?: string\n label?: string\n kind?: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata'\n default?: boolean\n}\n\n// Embedded content\ninterface IframeHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n srcDoc?: string\n name?: string\n width?: number | string\n height?: number | string\n allow?: string\n allowFullScreen?: boolean\n sandbox?: string\n loading?: 'eager' | 'lazy'\n referrerPolicy?: ReferrerPolicy\n}\n\ninterface EmbedHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n type?: string\n width?: number | string\n height?: number | string\n}\n\ninterface ObjectHTMLAttributes<T> extends HTMLAttributes<T> {\n data?: string\n type?: string\n name?: string\n width?: number | string\n height?: number | string\n form?: string\n useMap?: string\n}\n\ninterface ParamHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n value?: string\n}\n\ninterface CanvasHTMLAttributes<T> extends HTMLAttributes<T> {\n width?: number | string\n height?: number | string\n}\n\ninterface MapHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n}\n\ninterface AreaHTMLAttributes<T> extends HTMLAttributes<T> {\n alt?: string\n coords?: string\n href?: string\n hreflang?: string\n download?: boolean | string\n rel?: string\n shape?: 'rect' | 'circle' | 'poly' | 'default'\n target?: string\n referrerPolicy?: ReferrerPolicy\n ping?: string\n}\n\n// Interactive elements\ninterface DetailsHTMLAttributes<T> extends HTMLAttributes<T> {\n open?: boolean\n onToggle?: (e: Event) => void\n}\n\ninterface DialogHTMLAttributes<T> extends HTMLAttributes<T> {\n open?: boolean\n onClose?: (e: Event) => void\n onCancel?: (e: Event) => void\n}\n\n// Other elements\ninterface BlockquoteHTMLAttributes<T> extends HTMLAttributes<T> {\n cite?: string\n}\n\ninterface QuoteHTMLAttributes<T> extends HTMLAttributes<T> {\n cite?: string\n}\n\ninterface TimeHTMLAttributes<T> extends HTMLAttributes<T> {\n dateTime?: string\n}\n\ninterface DataHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string\n}\n\ninterface MetaHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n content?: string\n httpEquiv?: string\n charSet?: string\n property?: string\n}\n\ninterface LinkHTMLAttributes<T> extends HTMLAttributes<T> {\n href?: string\n rel?: string\n type?: string\n media?: string\n as?: string\n crossOrigin?: 'anonymous' | 'use-credentials'\n referrerPolicy?: ReferrerPolicy\n sizes?: string\n hreflang?: string\n integrity?: string\n fetchPriority?: 'auto' | 'high' | 'low'\n disabled?: boolean\n}\n\ninterface StyleHTMLAttributes<T> extends HTMLAttributes<T> {\n media?: string\n nonce?: string\n blocking?: string\n}\n\ninterface ScriptHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n type?: string\n async?: boolean\n defer?: boolean\n crossOrigin?: 'anonymous' | 'use-credentials'\n integrity?: string\n noModule?: boolean\n nonce?: string\n referrerPolicy?: ReferrerPolicy\n fetchPriority?: 'auto' | 'high' | 'low'\n blocking?: string\n}\n\ninterface SlotHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n onSlotchange?: (e: Event) => void\n}\n\n// SVG Attributes (basic support)\ninterface SVGAttributes<T> extends HTMLAttributes<T> {\n // Core SVG attributes\n viewBox?: string\n xmlns?: string\n xmlnsXlink?: string\n fill?: string\n stroke?: string\n strokeWidth?: string | number\n strokeLinecap?: 'butt' | 'round' | 'square'\n strokeLinejoin?: 'miter' | 'round' | 'bevel'\n strokeDasharray?: string\n strokeDashoffset?: string | number\n strokeOpacity?: string | number\n fillOpacity?: string | number\n opacity?: string | number\n transform?: string\n transformOrigin?: string\n clipPath?: string\n mask?: string\n filter?: string\n\n // Shape attributes\n d?: string\n cx?: string | number\n cy?: string | number\n r?: string | number\n rx?: string | number\n ry?: string | number\n x?: string | number\n y?: string | number\n x1?: string | number\n y1?: string | number\n x2?: string | number\n y2?: string | number\n width?: string | number\n height?: string | number\n points?: string\n pathLength?: string | number\n\n // Text attributes\n textAnchor?: 'start' | 'middle' | 'end'\n dominantBaseline?: string\n dx?: string | number\n dy?: string | number\n fontSize?: string | number\n fontFamily?: string\n fontWeight?: string | number\n\n // Use element\n href?: string\n xlinkHref?: string\n\n // Gradient/pattern\n gradientUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n gradientTransform?: string\n spreadMethod?: 'pad' | 'reflect' | 'repeat'\n offset?: string | number\n stopColor?: string\n stopOpacity?: string | number\n\n // Clip/mask\n clipPathUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n maskUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n maskContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n\n // Other\n preserveAspectRatio?: string\n markerStart?: string\n markerMid?: string\n markerEnd?: string\n vectorEffect?: string\n}\n"],"mappings":";AAEO,IAAM,WAAW,OAAO,UAAU;AAElC,SAAS,IACd,MACA,OACA,KACU;AACV,SAAO,EAAE,MAAM,OAAO,IAAI;AAC5B;AAEO,IAAM,OAAO;AACb,IAAM,SAAS;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/jsx.ts"],"sourcesContent":["import type { FictNode } from './types'\n\nexport const Fragment = Symbol('Fragment')\n\nexport function jsx(\n type: string | typeof Fragment | ((props: Record<string, unknown>) => FictNode),\n props: Record<string, unknown>,\n key?: string,\n): FictNode {\n return { type, props, key }\n}\n\nexport const jsxs = jsx\nexport const jsxDEV = jsx\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace JSX {\n export type Element = FictNode\n\n export interface IntrinsicElements {\n // Document structure\n html: HTMLAttributes<HTMLHtmlElement>\n head: HTMLAttributes<HTMLHeadElement>\n body: HTMLAttributes<HTMLBodyElement>\n title: HTMLAttributes<HTMLTitleElement>\n meta: MetaHTMLAttributes<HTMLMetaElement>\n link: LinkHTMLAttributes<HTMLLinkElement>\n style: StyleHTMLAttributes<HTMLStyleElement>\n script: ScriptHTMLAttributes<HTMLScriptElement>\n noscript: HTMLAttributes<HTMLElement>\n\n // Layout & Semantic\n div: HTMLAttributes<HTMLDivElement>\n span: HTMLAttributes<HTMLSpanElement>\n main: HTMLAttributes<HTMLElement>\n header: HTMLAttributes<HTMLElement>\n footer: HTMLAttributes<HTMLElement>\n section: HTMLAttributes<HTMLElement>\n article: HTMLAttributes<HTMLElement>\n aside: HTMLAttributes<HTMLElement>\n nav: HTMLAttributes<HTMLElement>\n address: HTMLAttributes<HTMLElement>\n\n // Headings\n h1: HTMLAttributes<HTMLHeadingElement>\n h2: HTMLAttributes<HTMLHeadingElement>\n h3: HTMLAttributes<HTMLHeadingElement>\n h4: HTMLAttributes<HTMLHeadingElement>\n h5: HTMLAttributes<HTMLHeadingElement>\n h6: HTMLAttributes<HTMLHeadingElement>\n hgroup: HTMLAttributes<HTMLElement>\n\n // Text content\n p: HTMLAttributes<HTMLParagraphElement>\n blockquote: BlockquoteHTMLAttributes<HTMLQuoteElement>\n pre: HTMLAttributes<HTMLPreElement>\n figure: HTMLAttributes<HTMLElement>\n figcaption: HTMLAttributes<HTMLElement>\n hr: HTMLAttributes<HTMLHRElement>\n br: HTMLAttributes<HTMLBRElement>\n wbr: HTMLAttributes<HTMLElement>\n\n // Inline text semantics\n a: AnchorHTMLAttributes<HTMLAnchorElement>\n abbr: HTMLAttributes<HTMLElement>\n b: HTMLAttributes<HTMLElement>\n bdi: HTMLAttributes<HTMLElement>\n bdo: HTMLAttributes<HTMLElement>\n cite: HTMLAttributes<HTMLElement>\n code: HTMLAttributes<HTMLElement>\n data: DataHTMLAttributes<HTMLDataElement>\n dfn: HTMLAttributes<HTMLElement>\n em: HTMLAttributes<HTMLElement>\n i: HTMLAttributes<HTMLElement>\n kbd: HTMLAttributes<HTMLElement>\n mark: HTMLAttributes<HTMLElement>\n q: QuoteHTMLAttributes<HTMLQuoteElement>\n rp: HTMLAttributes<HTMLElement>\n rt: HTMLAttributes<HTMLElement>\n ruby: HTMLAttributes<HTMLElement>\n s: HTMLAttributes<HTMLElement>\n samp: HTMLAttributes<HTMLElement>\n small: HTMLAttributes<HTMLElement>\n strong: HTMLAttributes<HTMLElement>\n sub: HTMLAttributes<HTMLElement>\n sup: HTMLAttributes<HTMLElement>\n time: TimeHTMLAttributes<HTMLTimeElement>\n u: HTMLAttributes<HTMLElement>\n var: HTMLAttributes<HTMLElement>\n\n // Lists\n ul: HTMLAttributes<HTMLUListElement>\n ol: OlHTMLAttributes<HTMLOListElement>\n li: LiHTMLAttributes<HTMLLIElement>\n dl: HTMLAttributes<HTMLDListElement>\n dt: HTMLAttributes<HTMLElement>\n dd: HTMLAttributes<HTMLElement>\n menu: HTMLAttributes<HTMLMenuElement>\n\n // Tables\n table: TableHTMLAttributes<HTMLTableElement>\n caption: HTMLAttributes<HTMLTableCaptionElement>\n colgroup: ColgroupHTMLAttributes<HTMLTableColElement>\n col: ColHTMLAttributes<HTMLTableColElement>\n thead: HTMLAttributes<HTMLTableSectionElement>\n tbody: HTMLAttributes<HTMLTableSectionElement>\n tfoot: HTMLAttributes<HTMLTableSectionElement>\n tr: HTMLAttributes<HTMLTableRowElement>\n th: ThHTMLAttributes<HTMLTableCellElement>\n td: TdHTMLAttributes<HTMLTableCellElement>\n\n // Forms\n form: FormHTMLAttributes<HTMLFormElement>\n fieldset: FieldsetHTMLAttributes<HTMLFieldSetElement>\n legend: HTMLAttributes<HTMLLegendElement>\n label: LabelHTMLAttributes<HTMLLabelElement>\n input: InputHTMLAttributes<HTMLInputElement>\n button: ButtonHTMLAttributes<HTMLButtonElement>\n select: SelectHTMLAttributes<HTMLSelectElement>\n datalist: HTMLAttributes<HTMLDataListElement>\n optgroup: OptgroupHTMLAttributes<HTMLOptGroupElement>\n option: OptionHTMLAttributes<HTMLOptionElement>\n textarea: TextareaHTMLAttributes<HTMLTextAreaElement>\n output: OutputHTMLAttributes<HTMLOutputElement>\n progress: ProgressHTMLAttributes<HTMLProgressElement>\n meter: MeterHTMLAttributes<HTMLMeterElement>\n\n // Interactive\n details: DetailsHTMLAttributes<HTMLDetailsElement>\n summary: HTMLAttributes<HTMLElement>\n dialog: DialogHTMLAttributes<HTMLDialogElement>\n\n // Media\n img: ImgHTMLAttributes<HTMLImageElement>\n picture: HTMLAttributes<HTMLPictureElement>\n source: SourceHTMLAttributes<HTMLSourceElement>\n audio: AudioVideoHTMLAttributes<HTMLAudioElement>\n video: AudioVideoHTMLAttributes<HTMLVideoElement>\n track: TrackHTMLAttributes<HTMLTrackElement>\n map: MapHTMLAttributes<HTMLMapElement>\n area: AreaHTMLAttributes<HTMLAreaElement>\n\n // Embedded content\n iframe: IframeHTMLAttributes<HTMLIFrameElement>\n embed: EmbedHTMLAttributes<HTMLEmbedElement>\n object: ObjectHTMLAttributes<HTMLObjectElement>\n param: ParamHTMLAttributes<HTMLParamElement>\n canvas: CanvasHTMLAttributes<HTMLCanvasElement>\n\n // SVG (basic support)\n svg: SVGAttributes<SVGSVGElement>\n path: SVGAttributes<SVGPathElement>\n circle: SVGAttributes<SVGCircleElement>\n rect: SVGAttributes<SVGRectElement>\n line: SVGAttributes<SVGLineElement>\n polyline: SVGAttributes<SVGPolylineElement>\n polygon: SVGAttributes<SVGPolygonElement>\n ellipse: SVGAttributes<SVGEllipseElement>\n g: SVGAttributes<SVGGElement>\n defs: SVGAttributes<SVGDefsElement>\n use: SVGAttributes<SVGUseElement>\n text: SVGAttributes<SVGTextElement>\n tspan: SVGAttributes<SVGTSpanElement>\n\n // Web components / other\n template: HTMLAttributes<HTMLTemplateElement>\n slot: SlotHTMLAttributes<HTMLSlotElement>\n portal: HTMLAttributes<HTMLElement>\n }\n\n export interface ElementChildrenAttribute {\n children: unknown\n }\n}\n\n// ============================================================================\n// Base HTML Attributes\n// ============================================================================\n\ninterface HTMLAttributes<T> {\n // Children\n children?: FictNode | FictNode[]\n\n // JSX special attributes\n key?: string | number\n\n // Core attributes\n id?: string\n class?: string\n style?: string | Record<string, string | number>\n title?: string\n lang?: string\n dir?: 'ltr' | 'rtl' | 'auto'\n hidden?: boolean | 'hidden' | 'until-found'\n tabIndex?: number\n draggable?: boolean | 'true' | 'false'\n contentEditable?: boolean | 'true' | 'false' | 'inherit'\n spellCheck?: boolean | 'true' | 'false'\n translate?: 'yes' | 'no'\n inert?: boolean\n popover?: 'auto' | 'manual'\n\n // Experimental / newer\n autofocus?: boolean\n slot?: string\n accessKey?: string\n\n // Event handlers\n onClick?: (e: MouseEvent) => void\n onClick$?: (e: MouseEvent) => void\n onDblClick?: (e: MouseEvent) => void\n onDblClick$?: (e: MouseEvent) => void\n onMouseDown?: (e: MouseEvent) => void\n onMouseDown$?: (e: MouseEvent) => void\n onMouseUp?: (e: MouseEvent) => void\n onMouseUp$?: (e: MouseEvent) => void\n onMouseMove?: (e: MouseEvent) => void\n onMouseMove$?: (e: MouseEvent) => void\n onMouseEnter?: (e: MouseEvent) => void\n onMouseEnter$?: (e: MouseEvent) => void\n onMouseLeave?: (e: MouseEvent) => void\n onMouseLeave$?: (e: MouseEvent) => void\n onMouseOver?: (e: MouseEvent) => void\n onMouseOver$?: (e: MouseEvent) => void\n onMouseOut?: (e: MouseEvent) => void\n onMouseOut$?: (e: MouseEvent) => void\n onContextMenu?: (e: MouseEvent) => void\n onContextMenu$?: (e: MouseEvent) => void\n onInput?: (e: InputEvent) => void\n onInput$?: (e: InputEvent) => void\n onChange?: (e: Event) => void\n onChange$?: (e: Event) => void\n onSubmit?: (e: SubmitEvent) => void\n onSubmit$?: (e: SubmitEvent) => void\n onReset?: (e: Event) => void\n onReset$?: (e: Event) => void\n onKeyDown?: (e: KeyboardEvent) => void\n onKeyDown$?: (e: KeyboardEvent) => void\n onKeyUp?: (e: KeyboardEvent) => void\n onKeyUp$?: (e: KeyboardEvent) => void\n onKeyPress?: (e: KeyboardEvent) => void\n onKeyPress$?: (e: KeyboardEvent) => void\n onFocus?: (e: FocusEvent) => void\n onFocus$?: (e: FocusEvent) => void\n onBlur?: (e: FocusEvent) => void\n onBlur$?: (e: FocusEvent) => void\n onScroll?: (e: Event) => void\n onScroll$?: (e: Event) => void\n onWheel?: (e: WheelEvent) => void\n onWheel$?: (e: WheelEvent) => void\n onLoad?: (e: Event) => void\n onLoad$?: (e: Event) => void\n onError?: (e: Event) => void\n onError$?: (e: Event) => void\n\n // Drag events\n onDrag?: (e: DragEvent) => void\n onDrag$?: (e: DragEvent) => void\n onDragStart?: (e: DragEvent) => void\n onDragStart$?: (e: DragEvent) => void\n onDragEnd?: (e: DragEvent) => void\n onDragEnd$?: (e: DragEvent) => void\n onDragEnter?: (e: DragEvent) => void\n onDragEnter$?: (e: DragEvent) => void\n onDragLeave?: (e: DragEvent) => void\n onDragLeave$?: (e: DragEvent) => void\n onDragOver?: (e: DragEvent) => void\n onDragOver$?: (e: DragEvent) => void\n onDrop?: (e: DragEvent) => void\n onDrop$?: (e: DragEvent) => void\n\n // Touch events\n onTouchStart?: (e: TouchEvent) => void\n onTouchStart$?: (e: TouchEvent) => void\n onTouchMove?: (e: TouchEvent) => void\n onTouchMove$?: (e: TouchEvent) => void\n onTouchEnd?: (e: TouchEvent) => void\n onTouchEnd$?: (e: TouchEvent) => void\n onTouchCancel?: (e: TouchEvent) => void\n onTouchCancel$?: (e: TouchEvent) => void\n\n // Animation events\n onAnimationStart?: (e: AnimationEvent) => void\n onAnimationStart$?: (e: AnimationEvent) => void\n onAnimationEnd?: (e: AnimationEvent) => void\n onAnimationEnd$?: (e: AnimationEvent) => void\n onAnimationIteration?: (e: AnimationEvent) => void\n onAnimationIteration$?: (e: AnimationEvent) => void\n onTransitionEnd?: (e: TransitionEvent) => void\n onTransitionEnd$?: (e: TransitionEvent) => void\n\n // Pointer events\n onPointerDown?: (e: PointerEvent) => void\n onPointerDown$?: (e: PointerEvent) => void\n onPointerUp?: (e: PointerEvent) => void\n onPointerUp$?: (e: PointerEvent) => void\n onPointerMove?: (e: PointerEvent) => void\n onPointerMove$?: (e: PointerEvent) => void\n onPointerEnter?: (e: PointerEvent) => void\n onPointerEnter$?: (e: PointerEvent) => void\n onPointerLeave?: (e: PointerEvent) => void\n onPointerLeave$?: (e: PointerEvent) => void\n onPointerOver?: (e: PointerEvent) => void\n onPointerOver$?: (e: PointerEvent) => void\n onPointerOut?: (e: PointerEvent) => void\n onPointerOut$?: (e: PointerEvent) => void\n onPointerCancel?: (e: PointerEvent) => void\n onPointerCancel$?: (e: PointerEvent) => void\n\n // Ref\n ref?: ((el: T | null) => void) | { current: T | null }\n\n // ARIA attributes (common ones)\n role?: string\n 'aria-hidden'?: boolean | 'true' | 'false'\n 'aria-label'?: string\n 'aria-labelledby'?: string\n 'aria-describedby'?: string\n 'aria-live'?: 'off' | 'polite' | 'assertive'\n 'aria-atomic'?: boolean | 'true' | 'false'\n 'aria-busy'?: boolean | 'true' | 'false'\n 'aria-current'?: boolean | 'true' | 'false' | 'page' | 'step' | 'location' | 'date' | 'time'\n 'aria-disabled'?: boolean | 'true' | 'false'\n 'aria-expanded'?: boolean | 'true' | 'false'\n 'aria-haspopup'?: boolean | 'true' | 'false' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'\n 'aria-pressed'?: boolean | 'true' | 'false' | 'mixed'\n 'aria-selected'?: boolean | 'true' | 'false'\n 'aria-checked'?: boolean | 'true' | 'false' | 'mixed'\n 'aria-controls'?: string\n 'aria-owns'?: string\n 'aria-activedescendant'?: string\n 'aria-valuemin'?: number\n 'aria-valuemax'?: number\n 'aria-valuenow'?: number\n 'aria-valuetext'?: string\n 'aria-orientation'?: 'horizontal' | 'vertical'\n 'aria-readonly'?: boolean | 'true' | 'false'\n 'aria-required'?: boolean | 'true' | 'false'\n 'aria-invalid'?: boolean | 'true' | 'false' | 'grammar' | 'spelling'\n 'aria-errormessage'?: string\n 'aria-modal'?: boolean | 'true' | 'false'\n 'aria-placeholder'?: string\n 'aria-sort'?: 'none' | 'ascending' | 'descending' | 'other'\n 'aria-colcount'?: number\n 'aria-colindex'?: number\n 'aria-colspan'?: number\n 'aria-rowcount'?: number\n 'aria-rowindex'?: number\n 'aria-rowspan'?: number\n 'aria-setsize'?: number\n 'aria-posinset'?: number\n 'aria-level'?: number\n 'aria-multiselectable'?: boolean | 'true' | 'false'\n 'aria-autocomplete'?: 'none' | 'inline' | 'list' | 'both'\n 'aria-details'?: string\n 'aria-keyshortcuts'?: string\n 'aria-roledescription'?: string\n\n // Data attributes via index signature\n [key: `data-${string}`]: string | number | boolean | undefined\n}\n\n// ============================================================================\n// Specialized Attribute Interfaces\n// ============================================================================\n\ninterface AnchorHTMLAttributes<T> extends HTMLAttributes<T> {\n href?: string\n target?: '_self' | '_blank' | '_parent' | '_top' | string\n rel?: string\n download?: boolean | string\n hreflang?: string\n type?: string\n referrerPolicy?: ReferrerPolicy\n ping?: string\n}\n\ninterface ButtonHTMLAttributes<T> extends HTMLAttributes<T> {\n type?: 'button' | 'submit' | 'reset'\n disabled?: boolean\n name?: string\n value?: string\n form?: string\n formAction?: string\n formEncType?: string\n formMethod?: string\n formNoValidate?: boolean\n formTarget?: string\n popovertarget?: string\n popovertargetaction?: 'show' | 'hide' | 'toggle'\n}\n\ninterface InputHTMLAttributes<T> extends HTMLAttributes<T> {\n type?: string\n value?: string | number | readonly string[]\n defaultValue?: string | number | readonly string[]\n checked?: boolean\n defaultChecked?: boolean\n disabled?: boolean\n placeholder?: string\n name?: string\n form?: string\n required?: boolean\n readonly?: boolean\n multiple?: boolean\n min?: number | string\n max?: number | string\n minLength?: number\n maxLength?: number\n step?: number | string\n pattern?: string\n size?: number\n accept?: string\n capture?: boolean | 'user' | 'environment'\n list?: string\n autoComplete?: string\n autoCapitalize?: string\n inputMode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'\n enterKeyHint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send'\n height?: number | string\n width?: number | string\n alt?: string\n src?: string\n formAction?: string\n formEncType?: string\n formMethod?: string\n formNoValidate?: boolean\n formTarget?: string\n}\n\ninterface FormHTMLAttributes<T> extends HTMLAttributes<T> {\n action?: string\n method?: 'get' | 'post' | 'dialog'\n encType?: string\n target?: string\n name?: string\n noValidate?: boolean\n autoComplete?: 'on' | 'off'\n acceptCharset?: string\n}\n\ninterface ImgHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n alt?: string\n width?: number | string\n height?: number | string\n srcSet?: string\n sizes?: string\n loading?: 'eager' | 'lazy'\n decoding?: 'async' | 'auto' | 'sync'\n crossOrigin?: 'anonymous' | 'use-credentials'\n referrerPolicy?: ReferrerPolicy\n useMap?: string\n isMap?: boolean\n fetchPriority?: 'auto' | 'high' | 'low'\n}\n\ninterface TextareaHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string | number\n defaultValue?: string\n disabled?: boolean\n placeholder?: string\n name?: string\n form?: string\n required?: boolean\n readonly?: boolean\n rows?: number\n cols?: number\n minLength?: number\n maxLength?: number\n wrap?: 'hard' | 'soft' | 'off'\n autoComplete?: string\n}\n\ninterface SelectHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string | number | readonly string[]\n defaultValue?: string | number | readonly string[]\n disabled?: boolean\n name?: string\n form?: string\n required?: boolean\n multiple?: boolean\n size?: number\n autoComplete?: string\n}\n\ninterface OptionHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string | number\n disabled?: boolean\n selected?: boolean\n label?: string\n}\n\ninterface OptgroupHTMLAttributes<T> extends HTMLAttributes<T> {\n disabled?: boolean\n label?: string\n}\n\ninterface LabelHTMLAttributes<T> extends HTMLAttributes<T> {\n for?: string\n htmlFor?: string\n form?: string\n}\n\ninterface FieldsetHTMLAttributes<T> extends HTMLAttributes<T> {\n disabled?: boolean\n name?: string\n form?: string\n}\n\ninterface OutputHTMLAttributes<T> extends HTMLAttributes<T> {\n for?: string\n htmlFor?: string\n form?: string\n name?: string\n}\n\ninterface ProgressHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: number | string\n max?: number | string\n}\n\ninterface MeterHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: number | string\n min?: number | string\n max?: number | string\n low?: number | string\n high?: number | string\n optimum?: number | string\n}\n\n// Table elements\ninterface TableHTMLAttributes<T> extends HTMLAttributes<T> {\n cellPadding?: number | string\n cellSpacing?: number | string\n border?: number | string\n}\n\ninterface ThHTMLAttributes<T> extends HTMLAttributes<T> {\n colSpan?: number\n rowSpan?: number\n scope?: 'row' | 'col' | 'rowgroup' | 'colgroup'\n abbr?: string\n headers?: string\n}\n\ninterface TdHTMLAttributes<T> extends HTMLAttributes<T> {\n colSpan?: number\n rowSpan?: number\n headers?: string\n}\n\ninterface ColHTMLAttributes<T> extends HTMLAttributes<T> {\n span?: number\n}\n\ninterface ColgroupHTMLAttributes<T> extends HTMLAttributes<T> {\n span?: number\n}\n\n// List elements\ninterface OlHTMLAttributes<T> extends HTMLAttributes<T> {\n start?: number\n reversed?: boolean\n type?: '1' | 'a' | 'A' | 'i' | 'I'\n}\n\ninterface LiHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: number\n}\n\n// Media elements\ninterface AudioVideoHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n controls?: boolean\n autoPlay?: boolean\n loop?: boolean\n muted?: boolean\n preload?: 'none' | 'metadata' | 'auto'\n crossOrigin?: 'anonymous' | 'use-credentials'\n poster?: string // video only\n width?: number | string // video only\n height?: number | string // video only\n playsInline?: boolean\n disableRemotePlayback?: boolean\n onPlay?: (e: Event) => void\n onPause?: (e: Event) => void\n onEnded?: (e: Event) => void\n onTimeUpdate?: (e: Event) => void\n onVolumeChange?: (e: Event) => void\n onSeeking?: (e: Event) => void\n onSeeked?: (e: Event) => void\n onLoadedData?: (e: Event) => void\n onLoadedMetadata?: (e: Event) => void\n onCanPlay?: (e: Event) => void\n onCanPlayThrough?: (e: Event) => void\n onWaiting?: (e: Event) => void\n onPlaying?: (e: Event) => void\n onProgress?: (e: Event) => void\n onDurationChange?: (e: Event) => void\n onRateChange?: (e: Event) => void\n onStalled?: (e: Event) => void\n onSuspend?: (e: Event) => void\n onEmptied?: (e: Event) => void\n}\n\ninterface SourceHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n srcSet?: string\n sizes?: string\n type?: string\n media?: string\n width?: number | string\n height?: number | string\n}\n\ninterface TrackHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n srcLang?: string\n label?: string\n kind?: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata'\n default?: boolean\n}\n\n// Embedded content\ninterface IframeHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n srcDoc?: string\n name?: string\n width?: number | string\n height?: number | string\n allow?: string\n allowFullScreen?: boolean\n sandbox?: string\n loading?: 'eager' | 'lazy'\n referrerPolicy?: ReferrerPolicy\n}\n\ninterface EmbedHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n type?: string\n width?: number | string\n height?: number | string\n}\n\ninterface ObjectHTMLAttributes<T> extends HTMLAttributes<T> {\n data?: string\n type?: string\n name?: string\n width?: number | string\n height?: number | string\n form?: string\n useMap?: string\n}\n\ninterface ParamHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n value?: string\n}\n\ninterface CanvasHTMLAttributes<T> extends HTMLAttributes<T> {\n width?: number | string\n height?: number | string\n}\n\ninterface MapHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n}\n\ninterface AreaHTMLAttributes<T> extends HTMLAttributes<T> {\n alt?: string\n coords?: string\n href?: string\n hreflang?: string\n download?: boolean | string\n rel?: string\n shape?: 'rect' | 'circle' | 'poly' | 'default'\n target?: string\n referrerPolicy?: ReferrerPolicy\n ping?: string\n}\n\n// Interactive elements\ninterface DetailsHTMLAttributes<T> extends HTMLAttributes<T> {\n open?: boolean\n onToggle?: (e: Event) => void\n}\n\ninterface DialogHTMLAttributes<T> extends HTMLAttributes<T> {\n open?: boolean\n onClose?: (e: Event) => void\n onCancel?: (e: Event) => void\n}\n\n// Other elements\ninterface BlockquoteHTMLAttributes<T> extends HTMLAttributes<T> {\n cite?: string\n}\n\ninterface QuoteHTMLAttributes<T> extends HTMLAttributes<T> {\n cite?: string\n}\n\ninterface TimeHTMLAttributes<T> extends HTMLAttributes<T> {\n dateTime?: string\n}\n\ninterface DataHTMLAttributes<T> extends HTMLAttributes<T> {\n value?: string\n}\n\ninterface MetaHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n content?: string\n httpEquiv?: string\n charSet?: string\n property?: string\n}\n\ninterface LinkHTMLAttributes<T> extends HTMLAttributes<T> {\n href?: string\n rel?: string\n type?: string\n media?: string\n as?: string\n crossOrigin?: 'anonymous' | 'use-credentials'\n referrerPolicy?: ReferrerPolicy\n sizes?: string\n hreflang?: string\n integrity?: string\n fetchPriority?: 'auto' | 'high' | 'low'\n disabled?: boolean\n}\n\ninterface StyleHTMLAttributes<T> extends HTMLAttributes<T> {\n media?: string\n nonce?: string\n blocking?: string\n}\n\ninterface ScriptHTMLAttributes<T> extends HTMLAttributes<T> {\n src?: string\n type?: string\n async?: boolean\n defer?: boolean\n crossOrigin?: 'anonymous' | 'use-credentials'\n integrity?: string\n noModule?: boolean\n nonce?: string\n referrerPolicy?: ReferrerPolicy\n fetchPriority?: 'auto' | 'high' | 'low'\n blocking?: string\n}\n\ninterface SlotHTMLAttributes<T> extends HTMLAttributes<T> {\n name?: string\n onSlotchange?: (e: Event) => void\n}\n\n// SVG Attributes (basic support)\ninterface SVGAttributes<T> extends HTMLAttributes<T> {\n // Core SVG attributes\n viewBox?: string\n xmlns?: string\n xmlnsXlink?: string\n fill?: string\n stroke?: string\n strokeWidth?: string | number\n strokeLinecap?: 'butt' | 'round' | 'square'\n strokeLinejoin?: 'miter' | 'round' | 'bevel'\n strokeDasharray?: string\n strokeDashoffset?: string | number\n strokeOpacity?: string | number\n fillOpacity?: string | number\n opacity?: string | number\n transform?: string\n transformOrigin?: string\n clipPath?: string\n mask?: string\n filter?: string\n\n // Shape attributes\n d?: string\n cx?: string | number\n cy?: string | number\n r?: string | number\n rx?: string | number\n ry?: string | number\n x?: string | number\n y?: string | number\n x1?: string | number\n y1?: string | number\n x2?: string | number\n y2?: string | number\n width?: string | number\n height?: string | number\n points?: string\n pathLength?: string | number\n\n // Text attributes\n textAnchor?: 'start' | 'middle' | 'end'\n dominantBaseline?: string\n dx?: string | number\n dy?: string | number\n fontSize?: string | number\n fontFamily?: string\n fontWeight?: string | number\n\n // Use element\n href?: string\n xlinkHref?: string\n\n // Gradient/pattern\n gradientUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n gradientTransform?: string\n spreadMethod?: 'pad' | 'reflect' | 'repeat'\n offset?: string | number\n stopColor?: string\n stopOpacity?: string | number\n\n // Clip/mask\n clipPathUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n maskUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n maskContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox'\n\n // Other\n preserveAspectRatio?: string\n markerStart?: string\n markerMid?: string\n markerEnd?: string\n vectorEffect?: string\n}\n"],"mappings":";AAEO,IAAM,WAAW,OAAO,UAAU;AAElC,SAAS,IACd,MACA,OACA,KACU;AACV,SAAO,EAAE,MAAM,OAAO,IAAI;AAC5B;AAEO,IAAM,OAAO;AACb,IAAM,SAAS;","names":[]}
|
package/dist/loader.cjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkNBDEMBBXcjs = require('./chunk-NBDEMBBX.cjs');
|
|
12
12
|
|
|
13
13
|
// src/loader.ts
|
|
14
14
|
function resolveModuleUrl(url) {
|
|
@@ -21,6 +21,89 @@ function resolveModuleUrl(url) {
|
|
|
21
21
|
}
|
|
22
22
|
return url;
|
|
23
23
|
}
|
|
24
|
+
function resolveAbsoluteModuleUrl(url, ownerDocument) {
|
|
25
|
+
const baseUrl = _nullishCoalesce(_optionalChain([ownerDocument, 'optionalAccess', _ => _.baseURI]), () => ( (typeof document !== "undefined" ? document.baseURI : void 0)));
|
|
26
|
+
if (!baseUrl) return url;
|
|
27
|
+
try {
|
|
28
|
+
return new URL(url, baseUrl).href;
|
|
29
|
+
} catch (e) {
|
|
30
|
+
return url;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function normalizeImportUrl(url) {
|
|
34
|
+
if (!url.startsWith("data:")) {
|
|
35
|
+
return url;
|
|
36
|
+
}
|
|
37
|
+
const dataSeparatorIndex = url.indexOf(",");
|
|
38
|
+
if (dataSeparatorIndex === -1) {
|
|
39
|
+
return url;
|
|
40
|
+
}
|
|
41
|
+
const metadata = url.slice(0, dataSeparatorIndex);
|
|
42
|
+
const payload = url.slice(dataSeparatorIndex + 1);
|
|
43
|
+
if (metadata.includes(";base64")) {
|
|
44
|
+
return url;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return `${metadata},${encodeURIComponent(decodeURIComponent(payload))}`;
|
|
48
|
+
} catch (e2) {
|
|
49
|
+
return `${metadata},${encodeURIComponent(payload)}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function captureControlState(node, event) {
|
|
53
|
+
if (event.type !== "input" && event.type !== "change") return null;
|
|
54
|
+
if (node instanceof HTMLInputElement) {
|
|
55
|
+
if (node.type === "file") return null;
|
|
56
|
+
if (node.type === "checkbox" || node.type === "radio") {
|
|
57
|
+
return { checked: node.checked };
|
|
58
|
+
}
|
|
59
|
+
return { value: node.value };
|
|
60
|
+
}
|
|
61
|
+
if (node instanceof HTMLTextAreaElement) {
|
|
62
|
+
return { value: node.value };
|
|
63
|
+
}
|
|
64
|
+
if (node instanceof HTMLSelectElement) {
|
|
65
|
+
return node.multiple ? {
|
|
66
|
+
selectedValues: Array.from(node.selectedOptions).map((option) => option.value)
|
|
67
|
+
} : {
|
|
68
|
+
value: node.value,
|
|
69
|
+
selectedIndex: node.selectedIndex
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
function restoreControlState(node, state) {
|
|
75
|
+
if (!state) return;
|
|
76
|
+
if (node instanceof HTMLInputElement) {
|
|
77
|
+
if (typeof state.checked === "boolean") {
|
|
78
|
+
node.checked = state.checked;
|
|
79
|
+
}
|
|
80
|
+
if (typeof state.value === "string" && node.type !== "file") {
|
|
81
|
+
node.value = state.value;
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (node instanceof HTMLTextAreaElement) {
|
|
86
|
+
if (typeof state.value === "string") {
|
|
87
|
+
node.value = state.value;
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (node instanceof HTMLSelectElement) {
|
|
92
|
+
if (Array.isArray(state.selectedValues) && node.multiple) {
|
|
93
|
+
const selected = new Set(state.selectedValues);
|
|
94
|
+
for (const option of Array.from(node.options)) {
|
|
95
|
+
option.selected = selected.has(option.value);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (typeof state.selectedIndex === "number") {
|
|
100
|
+
node.selectedIndex = state.selectedIndex;
|
|
101
|
+
}
|
|
102
|
+
if (typeof state.value === "string") {
|
|
103
|
+
node.value = state.value;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
24
107
|
var hydratedScopes = /* @__PURE__ */ new Set();
|
|
25
108
|
var prefetchedUrls = /* @__PURE__ */ new Set();
|
|
26
109
|
var prefetchCleanup = null;
|
|
@@ -54,7 +137,7 @@ function installResumableLoader(options = {}) {
|
|
|
54
137
|
prefetchedUrls.clear();
|
|
55
138
|
processedSnapshots.clear();
|
|
56
139
|
emittedIssueKeys.clear();
|
|
57
|
-
|
|
140
|
+
_chunkNBDEMBBXcjs.__fictSetSSRState.call(void 0, null);
|
|
58
141
|
if (eventListenerCleanup) {
|
|
59
142
|
eventListenerCleanup();
|
|
60
143
|
eventListenerCleanup = null;
|
|
@@ -68,10 +151,10 @@ function installResumableLoader(options = {}) {
|
|
|
68
151
|
snapshotObserver = null;
|
|
69
152
|
}
|
|
70
153
|
const snapshotEl = doc.getElementById(scriptId);
|
|
71
|
-
if (_optionalChain([snapshotEl, 'optionalAccess',
|
|
154
|
+
if (_optionalChain([snapshotEl, 'optionalAccess', _2 => _2.textContent])) {
|
|
72
155
|
const state = parseSnapshotText(snapshotEl.textContent, `#${scriptId}`);
|
|
73
156
|
if (state) {
|
|
74
|
-
|
|
157
|
+
_chunkNBDEMBBXcjs.__fictSetSSRState.call(void 0, state);
|
|
75
158
|
}
|
|
76
159
|
}
|
|
77
160
|
const snapshotScripts = doc.querySelectorAll(
|
|
@@ -91,7 +174,7 @@ function installResumableLoader(options = {}) {
|
|
|
91
174
|
parseSnapshotScript(script);
|
|
92
175
|
}
|
|
93
176
|
}
|
|
94
|
-
const nested = _optionalChain([node, 'access',
|
|
177
|
+
const nested = _optionalChain([node, 'access', _3 => _3.querySelectorAll, 'optionalCall', _4 => _4(
|
|
95
178
|
'script[type="application/json"][data-fict-snapshot]'
|
|
96
179
|
)]);
|
|
97
180
|
if (nested && nested.length) {
|
|
@@ -104,8 +187,8 @@ function installResumableLoader(options = {}) {
|
|
|
104
187
|
});
|
|
105
188
|
snapshotObserver.observe(_nullishCoalesce(doc.documentElement, () => ( doc)), { childList: true, subtree: true });
|
|
106
189
|
}
|
|
107
|
-
|
|
108
|
-
const events = _nullishCoalesce(options.events, () => ( Array.from(
|
|
190
|
+
_chunkNBDEMBBXcjs.__fictEnableResumable.call(void 0, );
|
|
191
|
+
const events = _nullishCoalesce(options.events, () => ( Array.from(_chunkNBDEMBBXcjs.DelegatedEvents)));
|
|
109
192
|
for (const eventName of events) {
|
|
110
193
|
doc.addEventListener(eventName, handleResumableEvent, true);
|
|
111
194
|
}
|
|
@@ -129,19 +212,19 @@ function parseSnapshotScript(script) {
|
|
|
129
212
|
const source = script.id ? `#${script.id}` : "<script[data-fict-snapshot]>";
|
|
130
213
|
const state = parseSnapshotText(text, source);
|
|
131
214
|
if (state) {
|
|
132
|
-
|
|
215
|
+
_chunkNBDEMBBXcjs.__fictMergeSSRState.call(void 0, state);
|
|
133
216
|
}
|
|
134
217
|
}
|
|
135
218
|
function parseSnapshotText(text, source) {
|
|
136
219
|
let parsed;
|
|
137
220
|
try {
|
|
138
221
|
parsed = JSON.parse(text);
|
|
139
|
-
} catch (
|
|
222
|
+
} catch (e3) {
|
|
140
223
|
emitSnapshotIssue({
|
|
141
224
|
code: "snapshot_parse_error",
|
|
142
225
|
message: "[fict/loader] Failed to parse SSR snapshot JSON.",
|
|
143
226
|
source,
|
|
144
|
-
expectedVersion:
|
|
227
|
+
expectedVersion: _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION
|
|
145
228
|
});
|
|
146
229
|
return null;
|
|
147
230
|
}
|
|
@@ -153,18 +236,18 @@ function normalizeSnapshotState(value, source) {
|
|
|
153
236
|
code: "snapshot_invalid_shape",
|
|
154
237
|
message: "[fict/loader] Snapshot payload must be an object.",
|
|
155
238
|
source,
|
|
156
|
-
expectedVersion:
|
|
239
|
+
expectedVersion: _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION
|
|
157
240
|
});
|
|
158
241
|
return null;
|
|
159
242
|
}
|
|
160
243
|
const rawVersion = value.v;
|
|
161
|
-
const version = rawVersion === void 0 ?
|
|
162
|
-
if (!Number.isInteger(version) || version !==
|
|
244
|
+
const version = rawVersion === void 0 ? _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION : rawVersion;
|
|
245
|
+
if (!Number.isInteger(version) || version !== _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION) {
|
|
163
246
|
const versionIssue = {
|
|
164
247
|
code: "snapshot_unsupported_version",
|
|
165
248
|
message: `[fict/loader] Snapshot schema version ${String(version)} is not supported by this runtime.`,
|
|
166
249
|
source,
|
|
167
|
-
expectedVersion:
|
|
250
|
+
expectedVersion: _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION
|
|
168
251
|
};
|
|
169
252
|
if (typeof version === "number") {
|
|
170
253
|
versionIssue.actualVersion = version;
|
|
@@ -180,11 +263,11 @@ function normalizeSnapshotState(value, source) {
|
|
|
180
263
|
code: "snapshot_invalid_shape",
|
|
181
264
|
message: "[fict/loader] Snapshot payload is missing a valid `scopes` object.",
|
|
182
265
|
source,
|
|
183
|
-
expectedVersion:
|
|
266
|
+
expectedVersion: _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION
|
|
184
267
|
});
|
|
185
268
|
return null;
|
|
186
269
|
}
|
|
187
|
-
return { v:
|
|
270
|
+
return { v: _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION, scopes };
|
|
188
271
|
}
|
|
189
272
|
function isRecord(value) {
|
|
190
273
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -193,7 +276,7 @@ function emitSnapshotIssue(issue) {
|
|
|
193
276
|
const key = `${issue.code}|${issue.source}|${_nullishCoalesce(issue.scopeId, () => ( ""))}|${_nullishCoalesce(issue.actualVersion, () => ( ""))}|${issue.expectedVersion}`;
|
|
194
277
|
if (emittedIssueKeys.has(key)) return;
|
|
195
278
|
emittedIssueKeys.add(key);
|
|
196
|
-
_optionalChain([snapshotIssueHandler, 'optionalCall',
|
|
279
|
+
_optionalChain([snapshotIssueHandler, 'optionalCall', _5 => _5(issue)]);
|
|
197
280
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
198
281
|
console.warn(issue.message);
|
|
199
282
|
}
|
|
@@ -314,7 +397,7 @@ function prefetchQrl(qrl, ownerDocument) {
|
|
|
314
397
|
link.rel = "modulepreload";
|
|
315
398
|
link.href = resolvedUrl;
|
|
316
399
|
link.crossOrigin = "anonymous";
|
|
317
|
-
_optionalChain([doc, 'access',
|
|
400
|
+
_optionalChain([doc, 'access', _6 => _6.head, 'optionalAccess', _7 => _7.appendChild, 'call', _8 => _8(link)]);
|
|
318
401
|
}
|
|
319
402
|
}
|
|
320
403
|
function handleResumableEvent(event) {
|
|
@@ -338,18 +421,18 @@ async function handleResumableEventAsync(event) {
|
|
|
338
421
|
if (!host) continue;
|
|
339
422
|
const scopeId = host.getAttribute("data-fict-s");
|
|
340
423
|
if (!scopeId) continue;
|
|
341
|
-
const snapshot =
|
|
424
|
+
const snapshot = _chunkNBDEMBBXcjs.__fictGetSSRScope.call(void 0, scopeId);
|
|
342
425
|
if (!snapshot) {
|
|
343
426
|
emitSnapshotIssue({
|
|
344
427
|
code: "scope_snapshot_missing",
|
|
345
428
|
message: `[fict/loader] Missing scope snapshot for ${scopeId}; skipping resumable handler execution.`,
|
|
346
429
|
source: "event",
|
|
347
|
-
expectedVersion:
|
|
430
|
+
expectedVersion: _chunkNBDEMBBXcjs.FICT_SSR_SNAPSHOT_SCHEMA_VERSION,
|
|
348
431
|
scopeId
|
|
349
432
|
});
|
|
350
433
|
continue;
|
|
351
434
|
}
|
|
352
|
-
|
|
435
|
+
_chunkNBDEMBBXcjs.__fictEnsureScope.call(void 0, scopeId, host, snapshot);
|
|
353
436
|
const { url, exportName } = parseQrl(qrl);
|
|
354
437
|
if (event.cancelable && (event.type === "click" || event.type === "submit")) {
|
|
355
438
|
const tag = node.tagName.toLowerCase();
|
|
@@ -357,30 +440,64 @@ async function handleResumableEventAsync(event) {
|
|
|
357
440
|
event.preventDefault();
|
|
358
441
|
}
|
|
359
442
|
}
|
|
443
|
+
const preservedControlState = captureControlState(node, event);
|
|
444
|
+
let resumedDuringEvent = false;
|
|
360
445
|
if (!hydratedScopes.has(scopeId)) {
|
|
361
446
|
const resumeQrl = host.getAttribute("data-fict-h");
|
|
362
447
|
if (resumeQrl) {
|
|
363
448
|
const { url: resumeUrl, exportName: resumeExport } = parseQrl(resumeQrl);
|
|
364
449
|
const resolvedResumeUrl = resolveModuleUrl(resumeUrl);
|
|
450
|
+
const resolvedAbsoluteResumeUrl = resolveAbsoluteModuleUrl(
|
|
451
|
+
resolvedResumeUrl,
|
|
452
|
+
_nullishCoalesce(host.ownerDocument, () => ( void 0))
|
|
453
|
+
);
|
|
454
|
+
const resolvedResumeQrl = `${resolvedResumeUrl}#${resumeExport}`;
|
|
455
|
+
const resolvedAbsoluteResumeQrl = `${resolvedAbsoluteResumeUrl}#${resumeExport}`;
|
|
456
|
+
const normalizedResumeImportUrl = normalizeImportUrl(resolvedResumeUrl);
|
|
365
457
|
await Promise.resolve().then(() => _interopRequireWildcard(require(
|
|
366
458
|
/* @vite-ignore */
|
|
367
|
-
|
|
459
|
+
normalizedResumeImportUrl
|
|
368
460
|
)));
|
|
369
|
-
const resumeFn =
|
|
461
|
+
const resumeFn = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_chunkNBDEMBBXcjs.__fictGetResume.call(void 0, resumeQrl), () => ( _chunkNBDEMBBXcjs.__fictGetResume.call(void 0, resolvedResumeQrl))), () => ( _chunkNBDEMBBXcjs.__fictGetResume.call(void 0, resolvedAbsoluteResumeQrl))), () => ( _chunkNBDEMBBXcjs.__fictGetResume.call(void 0, resumeExport)));
|
|
370
462
|
if (typeof resumeFn === "function") {
|
|
371
463
|
await resumeFn(scopeId, host);
|
|
372
464
|
hydratedScopes.add(scopeId);
|
|
465
|
+
resumedDuringEvent = true;
|
|
373
466
|
}
|
|
374
467
|
}
|
|
375
468
|
}
|
|
469
|
+
if (resumedDuringEvent) {
|
|
470
|
+
restoreControlState(node, preservedControlState);
|
|
471
|
+
}
|
|
376
472
|
const resolvedUrl = resolveModuleUrl(url);
|
|
473
|
+
const normalizedImportUrl = normalizeImportUrl(resolvedUrl);
|
|
377
474
|
const mod = await Promise.resolve().then(() => _interopRequireWildcard(require(
|
|
378
475
|
/* @vite-ignore */
|
|
379
|
-
|
|
476
|
+
normalizedImportUrl
|
|
380
477
|
)));
|
|
381
478
|
const handler = mod[exportName];
|
|
382
479
|
if (typeof handler === "function") {
|
|
383
|
-
|
|
480
|
+
const originalCurrentTarget = event.currentTarget;
|
|
481
|
+
Object.defineProperty(event, "currentTarget", {
|
|
482
|
+
configurable: true,
|
|
483
|
+
get() {
|
|
484
|
+
return node;
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
try {
|
|
488
|
+
await handler(
|
|
489
|
+
scopeId,
|
|
490
|
+
event,
|
|
491
|
+
node
|
|
492
|
+
);
|
|
493
|
+
} finally {
|
|
494
|
+
Object.defineProperty(event, "currentTarget", {
|
|
495
|
+
configurable: true,
|
|
496
|
+
get() {
|
|
497
|
+
return originalCurrentTarget;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
384
501
|
}
|
|
385
502
|
return;
|
|
386
503
|
}
|
|
@@ -413,5 +530,5 @@ function buildEventPath(event) {
|
|
|
413
530
|
|
|
414
531
|
|
|
415
532
|
|
|
416
|
-
exports.__fictUseLexicalScope =
|
|
533
|
+
exports.__fictUseLexicalScope = _chunkNBDEMBBXcjs.__fictUseLexicalScope; exports.cleanupEventListeners = cleanupEventListeners; exports.installResumableLoader = installResumableLoader; exports.resetHydratedScopes = resetHydratedScopes; exports.resetPrefetchedUrls = resetPrefetchedUrls; exports.waitForPendingHandlers = waitForPendingHandlers;
|
|
417
534
|
//# sourceMappingURL=loader.cjs.map
|
package/dist/loader.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/loader.cjs","../src/loader.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACUA,SAAS,gBAAA,CAAiB,GAAA,EAAqB;AAC7C,EAAA,MAAM,SAAA,EAAY,UAAA,CAAuC,iBAAA;AAIzD,EAAA,GAAA,CAAI,QAAA,EAAU;AAEZ,IAAA,MAAM,SAAA,EAAW,QAAA,CAAS,GAAG,CAAA;AAC7B,IAAA,GAAA,CAAI,QAAA,EAAU;AACZ,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT;AAmEA,IAAM,eAAA,kBAAiB,IAAI,GAAA,CAAY,CAAA;AACvC,IAAM,eAAA,kBAAiB,IAAI,GAAA,CAAY,CAAA;AACvC,IAAI,gBAAA,EAAuC,IAAA;AAC3C,IAAI,qBAAA,EAA4C,IAAA;AAChD,IAAI,iBAAA,EAA4C,IAAA;AAChD,IAAM,mBAAA,kBAAqB,IAAI,GAAA,CAAuB,CAAA;AACtD,IAAI,qBAAA,EAAgE,IAAA;AACpE,IAAM,iBAAA,kBAAmB,IAAI,GAAA,CAAY,CAAA;AAKlC,SAAS,mBAAA,CAAA,EAA4B;AAC1C,EAAA,cAAA,CAAe,KAAA,CAAM,CAAA;AACvB;AAKO,SAAS,mBAAA,CAAA,EAA4B;AAC1C,EAAA,cAAA,CAAe,KAAA,CAAM,CAAA;AACvB;AAKA,IAAM,gBAAA,kBAAkB,IAAI,GAAA,CAAmB,CAAA;AAK/C,MAAA,SAAsB,sBAAA,CAAA,EAAwC;AAC5D,EAAA,GAAA,CAAI,eAAA,CAAgB,KAAA,IAAS,CAAA,EAAG,MAAA;AAChC,EAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,CAAC,GAAG,eAAe,CAAC,CAAA;AAC/C;AAKO,SAAS,qBAAA,CAAA,EAA8B;AAC5C,EAAA,GAAA,CAAI,oBAAA,EAAsB;AACxB,IAAA,oBAAA,CAAqB,CAAA;AACrB,IAAA,qBAAA,EAAuB,IAAA;AAAA,EACzB;AACF;AAMO,SAAS,sBAAA,CAAuB,QAAA,EAAkC,CAAC,CAAA,EAAS;AACjF,EAAA,MAAM,IAAA,mBAAM,OAAA,CAAQ,QAAA,UAAY,MAAA,CAAO,UAAA;AACvC,EAAA,MAAM,SAAA,mBAAW,OAAA,CAAQ,gBAAA,UAAoB,qBAAA;AAC7C,EAAA,qBAAA,mBAAuB,OAAA,CAAQ,eAAA,UAAmB,MAAA;AAGlD,EAAA,cAAA,CAAe,KAAA,CAAM,CAAA;AACrB,EAAA,cAAA,CAAe,KAAA,CAAM,CAAA;AACrB,EAAA,kBAAA,CAAmB,KAAA,CAAM,CAAA;AACzB,EAAA,gBAAA,CAAiB,KAAA,CAAM,CAAA;AACvB,EAAA,iDAAA,IAAsB,CAAA;AAGtB,EAAA,GAAA,CAAI,oBAAA,EAAsB;AACxB,IAAA,oBAAA,CAAqB,CAAA;AACrB,IAAA,qBAAA,EAAuB,IAAA;AAAA,EACzB;AAGA,EAAA,GAAA,CAAI,eAAA,EAAiB;AACnB,IAAA,eAAA,CAAgB,CAAA;AAChB,IAAA,gBAAA,EAAkB,IAAA;AAAA,EACpB;AAEA,EAAA,GAAA,CAAI,gBAAA,EAAkB;AACpB,IAAA,gBAAA,CAAiB,UAAA,CAAW,CAAA;AAC5B,IAAA,iBAAA,EAAmB,IAAA;AAAA,EACrB;AAEA,EAAA,MAAM,WAAA,EAAa,GAAA,CAAI,cAAA,CAAe,QAAQ,CAAA;AAC9C,EAAA,GAAA,iBAAI,UAAA,2BAAY,aAAA,EAAa;AAC3B,IAAA,MAAM,MAAA,EAAQ,iBAAA,CAAkB,UAAA,CAAW,WAAA,EAAa,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AACzD,IAAA;AACc,MAAA;AACzB,IAAA;AACF,EAAA;AAE4B,EAAA;AAC1B,IAAA;AACF,EAAA;AACkD,EAAA;AACD,IAAA;AACjD,EAAA;AAE6C,EAAA;AACU,IAAA;AACjB,MAAA;AACoB,QAAA;AAClB,UAAA;AACD,UAAA;AACd,YAAA;AACe,YAAA;AACF,cAAA;AAC5B,YAAA;AACF,UAAA;AACoB,UAAA;AAClB,YAAA;AACF,UAAA;AAC6B,UAAA;AACc,YAAA;AACQ,cAAA;AACjD,YAAA;AACF,UAAA;AACF,QAAA;AACF,MAAA;AACD,IAAA;AACiE,IAAA;AACpE,EAAA;AAEsB,EAAA;AAEqC,EAAA;AAC3B,EAAA;AAC4B,IAAA;AAC5D,EAAA;AAG6B,EAAA;AACK,IAAA;AAC+B,MAAA;AAC/D,IAAA;AACF,EAAA;AAGgC,EAAA;AAC6B,IAAA;AAC7D,EAAA;AACF;AAE8D;AACK,EAAA;AACnE;AAE8D;AACxB,EAAA;AACP,EAAA;AACT,EAAA;AACT,EAAA;AACkC,EAAA;AACD,EAAA;AACjC,EAAA;AACgB,IAAA;AAC3B,EAAA;AACF;AAE0E;AACpE,EAAA;AACA,EAAA;AACsB,IAAA;AAClB,EAAA;AACY,IAAA;AACV,MAAA;AACG,MAAA;AACT,MAAA;AACiB,MAAA;AAClB,IAAA;AACM,IAAA;AACT,EAAA;AAE4C,EAAA;AAC9C;AAEiF;AACzD,EAAA;AACF,IAAA;AACV,MAAA;AACG,MAAA;AACT,MAAA;AACiB,MAAA;AAClB,IAAA;AACM,IAAA;AACT,EAAA;AAEyB,EAAA;AACkB,EAAA;AACG,EAAA;AACR,IAAA;AAC5B,MAAA;AAC2D,MAAA;AACjE,MAAA;AACiB,MAAA;AACnB,IAAA;AACiC,IAAA;AACF,MAAA;AAC/B,IAAA;AACkB,IAAA;AACb,MAAA;AACJ,IAAA;AACM,IAAA;AACT,EAAA;AAEqB,EAAA;AACE,EAAA;AACH,IAAA;AACV,MAAA;AACG,MAAA;AACT,MAAA;AACiB,MAAA;AAClB,IAAA;AACM,IAAA;AACT,EAAA;AAEmF,EAAA;AACrF;AAEoE;AACG,EAAA;AACvE;AAEuD;AAGhD,EAAA;AAC0B,EAAA;AACP,EAAA;AAEI,kBAAA;AAEkC,EAAA;AAClC,IAAA;AAC5B,EAAA;AACF;AAM8E;AACxC,EAAA;AAGD,EAAA;AACqB,IAAA;AAC/B,IAAA;AACzB,EAAA;AAG8B,EAAA;AACqC,IAAA;AAC1C,IAAA;AACzB,EAAA;AAEa,EAAA;AACuB,IAAA;AACxB,MAAA;AACV,IAAA;AACF,EAAA;AACF;AAEgF;AAE7B,EAAA;AAClC,IAAA;AAAC,IAAA;AAChB,EAAA;AAEqB,EAAA;AACR,IAAA;AACoB,MAAA;AACD,QAAA;AACP,UAAA;AACK,UAAA;AAED,UAAA;AACvB,QAAA;AACF,MAAA;AACF,IAAA;AACa,IAAA;AACf,EAAA;AAGgC,EAAA;AAC9B,IAAA;AACF,EAAA;AACsD,EAAA;AAGK,EAAA;AACV,EAAA;AAEpC,EAAA;AACS,IAAA;AACtB,EAAA;AACF;AAEsE;AACX,EAAA;AAChB,EAAA;AAEG,EAAA;AACrB,IAAA;AACa,IAAA;AAKzB,IAAA;AAKmD,IAAA;AAEvC,IAAA;AAGH,IAAA;AACS,MAAA;AAC3B,IAAA;AAGgC,IAAA;AACG,MAAA;AAC3B,IAAA;AACV,EAAA;AAE+B,EAAA;AACX,IAAA;AACS,MAAA;AACV,MAAA;AACjB,IAAA;AACqB,IAAA;AACvB,EAAA;AAEuE,EAAA;AACD,EAAA;AAEzD,EAAA;AAC6C,IAAA;AACF,IAAA;AACpC,IAAA;AACS,MAAA;AAC3B,IAAA;AACF,EAAA;AACF;AAEgD;AACiB,EAAA;AAEO,EAAA;AACvC,EAAA;AACG,IAAA;AACvB,IAAA;AACuB,MAAA;AAChC,IAAA;AACF,EAAA;AAG+C,EAAA;AAChC,EAAA;AACuB,IAAA;AACtC,EAAA;AAGoB,EAAA;AAClB,IAAA;AACF,EAAA;AAC0B,EAAA;AACO,IAAA;AACM,MAAA;AAC1B,MAAA;AACuB,QAAA;AAChC,MAAA;AACF,IAAA;AACuD,IAAA;AACnC,IAAA;AACuB,MAAA;AAC3C,IAAA;AACD,EAAA;AACH;AAEkE;AACpC,EAAA;AACS,EAAA;AAEf,EAAA;AAGkB,EAAA;AAGwB,EAAA;AACvD,EAAA;AAC8B,IAAA;AAC1B,IAAA;AACC,IAAA;AACO,IAAA;AACO,oBAAA;AAC5B,EAAA;AACF;AAOkD;AACD,EAAA;AACpB,EAAA;AAET,EAAA;AACiD,IAAA;AACI,MAAA;AACnE,IAAA;AAEa,EAAA;AACiB,IAAA;AAC/B,EAAA;AACL;AAEsE;AAEjB,EAAA;AAE1B,EAAA;AACS,IAAA;AACgB,IAAA;AACtC,IAAA;AAE+B,IAAA;AAC9B,IAAA;AACoC,IAAA;AACjC,IAAA;AAE4B,IAAA;AAC3B,IAAA;AACK,MAAA;AACV,QAAA;AACsD,QAAA;AACpD,QAAA;AACS,QAAA;AACjB,QAAA;AACD,MAAA;AACD,MAAA;AACF,IAAA;AACyC,IAAA;AAED,IAAA;AAG0B,IAAA;AAC3B,MAAA;AACF,MAAA;AACZ,QAAA;AACvB,MAAA;AACF,IAAA;AAGkC,IAAA;AACiB,MAAA;AAClC,MAAA;AACiD,QAAA;AACV,QAAA;AAE9C,QAAA;AAAA;AAA0B,UAAA;AAAA,QAAA;AAEa,QAAA;AACT,QAAA;AAC2C,UAAA;AACnD,UAAA;AAC5B,QAAA;AACF,MAAA;AACF,IAAA;AAGwC,IAAA;AACtB,IAAA;AAAA;AAA0B,MAAA;AAAA,IAAA;AACe,IAAA;AACxB,IAAA;AAC2D,MAAA;AAC9F,IAAA;AAEA,IAAA;AACF,EAAA;AACF;AAEoE;AACvC,EAAA;AACjB,EAAA;AACgC,IAAA;AAC1C,EAAA;AACqC,EAAA;AACf,EAAA;AACqB,IAAA;AAC3C,EAAA;AAC6D,EAAA;AAC/D;AAEqD;AACtB,EAAA;AACQ,EAAA;AACxB,EAAA;AACG,IAAA;AACQ,IAAA;AACxB,EAAA;AACgB,EAAA;AACT,EAAA;AACT;ADzMyE;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/fict/fict/packages/runtime/dist/loader.cjs","sourcesContent":[null,"import { DelegatedEvents } from './constants'\nimport {\n FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n type SSRState,\n __fictEnableResumable,\n __fictEnsureScope,\n __fictGetResume,\n __fictGetSSRScope,\n __fictMergeSSRState,\n __fictSetSSRState,\n __fictUseLexicalScope,\n} from './resume'\n\n// ============================================================================\n// Module Resolution\n// ============================================================================\n\n/**\n * Resolve a module URL through the manifest if available.\n * In production, virtual module URLs (virtual:fict-handler:...) are mapped\n * to their built chunk URLs through the manifest.\n */\nfunction resolveModuleUrl(url: string): string {\n const manifest = (globalThis as Record<string, unknown>).__FICT_MANIFEST__ as\n | Record<string, string>\n | undefined\n\n if (manifest) {\n // Check if the URL (without #fragment) is in the manifest\n const resolved = manifest[url]\n if (resolved) {\n return resolved\n }\n }\n\n return url\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PrefetchStrategy {\n /**\n * Enable visibility-based prefetch using IntersectionObserver.\n * Prefetches modules when interactive elements come into view.\n * @default true\n */\n visibility?: boolean\n /**\n * Root margin for IntersectionObserver (e.g., '200px' to prefetch earlier).\n * @default '200px'\n */\n visibilityMargin?: string\n /**\n * Enable hover-based prefetch using pointerover events.\n * Prefetches modules when user hovers over interactive elements.\n * @default true\n */\n hover?: boolean\n /**\n * Delay in ms before prefetching on hover (debounce rapid movements).\n * @default 50\n */\n hoverDelay?: number\n}\n\nexport interface ResumableLoaderOptions {\n document?: Document\n snapshotScriptId?: string\n events?: string[]\n /**\n * Receives structured snapshot/resume issues detected by the loader.\n * Useful for telemetry and fail-safe fallback orchestration.\n */\n onSnapshotIssue?: (issue: SnapshotIssue) => void\n /**\n * Prefetch strategy configuration.\n * Set to false to disable all prefetching.\n * @default { visibility: true, hover: true }\n */\n prefetch?: PrefetchStrategy | false\n}\n\nexport type SnapshotIssueCode =\n | 'snapshot_parse_error'\n | 'snapshot_invalid_shape'\n | 'snapshot_unsupported_version'\n | 'scope_snapshot_missing'\n\nexport interface SnapshotIssue {\n code: SnapshotIssueCode\n message: string\n source: string\n expectedVersion: number\n actualVersion?: number\n scopeId?: string\n}\n\n// ============================================================================\n// State\n// ============================================================================\n\nconst hydratedScopes = new Set<string>()\nconst prefetchedUrls = new Set<string>()\nlet prefetchCleanup: (() => void) | null = null\nlet eventListenerCleanup: (() => void) | null = null\nlet snapshotObserver: MutationObserver | null = null\nconst processedSnapshots = new Set<HTMLScriptElement>()\nlet snapshotIssueHandler: ((issue: SnapshotIssue) => void) | null = null\nconst emittedIssueKeys = new Set<string>()\n\n/**\n * Reset the hydrated scopes set. Useful for testing.\n */\nexport function resetHydratedScopes(): void {\n hydratedScopes.clear()\n}\n\n/**\n * Reset the prefetched URLs set. Useful for testing.\n */\nexport function resetPrefetchedUrls(): void {\n prefetchedUrls.clear()\n}\n\n/**\n * Set of pending handler promises. Used for testing to wait for all handlers to complete.\n */\nconst pendingHandlers = new Set<Promise<void>>()\n\n/**\n * Wait for all pending event handlers to complete. Useful for testing.\n */\nexport async function waitForPendingHandlers(): Promise<void> {\n if (pendingHandlers.size === 0) return\n await Promise.allSettled([...pendingHandlers])\n}\n\n/**\n * Clean up all registered event listeners. Useful for testing.\n */\nexport function cleanupEventListeners(): void {\n if (eventListenerCleanup) {\n eventListenerCleanup()\n eventListenerCleanup = null\n }\n}\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\nexport function installResumableLoader(options: ResumableLoaderOptions = {}): void {\n const doc = options.document ?? window.document\n const scriptId = options.snapshotScriptId ?? '__FICT_SNAPSHOT__'\n snapshotIssueHandler = options.onSnapshotIssue ?? null\n\n // Reset hydrated scopes for fresh loader installation\n hydratedScopes.clear()\n prefetchedUrls.clear()\n processedSnapshots.clear()\n emittedIssueKeys.clear()\n __fictSetSSRState(null)\n\n // Clean up previous event listeners\n if (eventListenerCleanup) {\n eventListenerCleanup()\n eventListenerCleanup = null\n }\n\n // Clean up previous prefetch handlers\n if (prefetchCleanup) {\n prefetchCleanup()\n prefetchCleanup = null\n }\n\n if (snapshotObserver) {\n snapshotObserver.disconnect()\n snapshotObserver = null\n }\n\n const snapshotEl = doc.getElementById(scriptId)\n if (snapshotEl?.textContent) {\n const state = parseSnapshotText(snapshotEl.textContent, `#${scriptId}`)\n if (state) {\n __fictSetSSRState(state)\n }\n }\n\n const snapshotScripts = doc.querySelectorAll(\n 'script[type=\"application/json\"][data-fict-snapshot]',\n )\n for (const script of Array.from(snapshotScripts)) {\n parseSnapshotScript(script as HTMLScriptElement)\n }\n\n if (typeof MutationObserver !== 'undefined') {\n snapshotObserver = new MutationObserver(mutations => {\n for (const mutation of mutations) {\n for (const node of Array.from(mutation.addedNodes)) {\n if (!(node instanceof Element)) continue\n if (node.tagName === 'SCRIPT') {\n const script = node as HTMLScriptElement\n if (isSnapshotScript(script)) {\n parseSnapshotScript(script)\n }\n }\n const nested = node.querySelectorAll?.(\n 'script[type=\"application/json\"][data-fict-snapshot]',\n )\n if (nested && nested.length) {\n for (const script of Array.from(nested)) {\n parseSnapshotScript(script as HTMLScriptElement)\n }\n }\n }\n }\n })\n snapshotObserver.observe(doc.documentElement ?? doc, { childList: true, subtree: true })\n }\n\n __fictEnableResumable()\n\n const events = options.events ?? Array.from(DelegatedEvents)\n for (const eventName of events) {\n doc.addEventListener(eventName, handleResumableEvent, true)\n }\n\n // Store cleanup function for event listeners\n eventListenerCleanup = () => {\n for (const eventName of events) {\n doc.removeEventListener(eventName, handleResumableEvent, true)\n }\n }\n\n // Setup prefetch if enabled\n if (options.prefetch !== false) {\n prefetchCleanup = setupPrefetch(doc, options.prefetch ?? {})\n }\n}\n\nfunction isSnapshotScript(script: HTMLScriptElement): boolean {\n return script.type === 'application/json' && script.hasAttribute('data-fict-snapshot')\n}\n\nfunction parseSnapshotScript(script: HTMLScriptElement): void {\n if (processedSnapshots.has(script)) return\n processedSnapshots.add(script)\n const text = script.textContent\n if (!text) return\n const source = script.id ? `#${script.id}` : '<script[data-fict-snapshot]>'\n const state = parseSnapshotText(text, source)\n if (state) {\n __fictMergeSSRState(state)\n }\n}\n\nfunction parseSnapshotText(text: string, source: string): SSRState | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n emitSnapshotIssue({\n code: 'snapshot_parse_error',\n message: '[fict/loader] Failed to parse SSR snapshot JSON.',\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n })\n return null\n }\n\n return normalizeSnapshotState(parsed, source)\n}\n\nfunction normalizeSnapshotState(value: unknown, source: string): SSRState | null {\n if (!isRecord(value)) {\n emitSnapshotIssue({\n code: 'snapshot_invalid_shape',\n message: '[fict/loader] Snapshot payload must be an object.',\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n })\n return null\n }\n\n const rawVersion = value.v\n const version = rawVersion === undefined ? FICT_SSR_SNAPSHOT_SCHEMA_VERSION : rawVersion\n if (!Number.isInteger(version) || version !== FICT_SSR_SNAPSHOT_SCHEMA_VERSION) {\n const versionIssue: SnapshotIssue = {\n code: 'snapshot_unsupported_version',\n message: `[fict/loader] Snapshot schema version ${String(version)} is not supported by this runtime.`,\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n }\n if (typeof version === 'number') {\n versionIssue.actualVersion = version\n }\n emitSnapshotIssue({\n ...versionIssue,\n })\n return null\n }\n\n const scopes = value.scopes\n if (!isRecord(scopes)) {\n emitSnapshotIssue({\n code: 'snapshot_invalid_shape',\n message: '[fict/loader] Snapshot payload is missing a valid `scopes` object.',\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n })\n return null\n }\n\n return { v: FICT_SSR_SNAPSHOT_SCHEMA_VERSION, scopes: scopes as SSRState['scopes'] }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction emitSnapshotIssue(issue: SnapshotIssue): void {\n const key =\n `${issue.code}|${issue.source}|${issue.scopeId ?? ''}|` +\n `${issue.actualVersion ?? ''}|${issue.expectedVersion}`\n if (emittedIssueKeys.has(key)) return\n emittedIssueKeys.add(key)\n\n snapshotIssueHandler?.(issue)\n\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(issue.message)\n }\n}\n\n// ============================================================================\n// Prefetch Implementation\n// ============================================================================\n\nfunction setupPrefetch(doc: Document, strategy: PrefetchStrategy): () => void {\n const cleanupFns: (() => void)[] = []\n\n // Visibility-based prefetch\n if (strategy.visibility !== false) {\n const cleanup = setupVisibilityPrefetch(doc, strategy.visibilityMargin ?? '200px')\n cleanupFns.push(cleanup)\n }\n\n // Hover-based prefetch\n if (strategy.hover !== false) {\n const cleanup = setupHoverPrefetch(doc, strategy.hoverDelay ?? 50)\n cleanupFns.push(cleanup)\n }\n\n return () => {\n for (const cleanup of cleanupFns) {\n cleanup()\n }\n }\n}\n\nfunction setupVisibilityPrefetch(doc: Document, rootMargin: string): () => void {\n // Check if IntersectionObserver is available\n if (typeof IntersectionObserver === 'undefined') {\n return () => {}\n }\n\n const observer = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const el = entry.target as Element\n prefetchElementQrls(el)\n // Stop observing after prefetch\n observer.unobserve(el)\n }\n }\n },\n { rootMargin },\n )\n\n // Observe all elements with on:* attributes\n const interactiveElements = doc.querySelectorAll(\n '[on\\\\:click], [on\\\\:input], [on\\\\:change], [on\\\\:submit], [on\\\\:keydown], [on\\\\:keyup]',\n )\n interactiveElements.forEach(el => observer.observe(el))\n\n // Also observe elements with data-fict-h (resumable components)\n const resumableHosts = doc.querySelectorAll('[data-fict-h]')\n resumableHosts.forEach(el => observer.observe(el))\n\n return () => {\n observer.disconnect()\n }\n}\n\nfunction setupHoverPrefetch(doc: Document, delay: number): () => void {\n let hoverTimeout: ReturnType<typeof setTimeout> | null = null\n let lastHoveredElement: Element | null = null\n\n const handlePointerOver = (event: Event) => {\n const target = event.target\n if (!(target instanceof Element)) return\n\n // Find the closest element with interactive attributes\n const interactiveEl =\n target.closest('[on\\\\:click]') ||\n target.closest('[on\\\\:input]') ||\n target.closest('[on\\\\:change]') ||\n target.closest('[on\\\\:submit]') ||\n target.closest('[data-fict-h]')\n\n if (!interactiveEl || interactiveEl === lastHoveredElement) return\n\n lastHoveredElement = interactiveEl\n\n // Clear previous timeout\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n }\n\n // Debounce prefetch\n hoverTimeout = setTimeout(() => {\n prefetchElementQrls(interactiveEl)\n }, delay)\n }\n\n const handlePointerOut = () => {\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n hoverTimeout = null\n }\n lastHoveredElement = null\n }\n\n doc.addEventListener('pointerover', handlePointerOver, { passive: true })\n doc.addEventListener('pointerout', handlePointerOut, { passive: true })\n\n return () => {\n doc.removeEventListener('pointerover', handlePointerOver)\n doc.removeEventListener('pointerout', handlePointerOut)\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n }\n }\n}\n\nfunction prefetchElementQrls(el: Element): void {\n const ownerDocument = el.ownerDocument ?? (typeof document !== 'undefined' ? document : undefined)\n // Prefetch event handler QRLs\n const eventAttrs = ['on:click', 'on:input', 'on:change', 'on:submit', 'on:keydown', 'on:keyup']\n for (const attr of eventAttrs) {\n const qrl = el.getAttribute(attr)\n if (qrl) {\n prefetchQrl(qrl, ownerDocument)\n }\n }\n\n // Prefetch resume handler QRL\n const resumeQrl = el.getAttribute('data-fict-h')\n if (resumeQrl) {\n prefetchQrl(resumeQrl, ownerDocument)\n }\n\n // Also check children for nested QRLs\n const children = el.querySelectorAll(\n '[on\\\\:click], [on\\\\:input], [on\\\\:change], [on\\\\:submit], [data-fict-h]',\n )\n children.forEach(child => {\n for (const attr of eventAttrs) {\n const qrl = child.getAttribute(attr)\n if (qrl) {\n prefetchQrl(qrl, ownerDocument)\n }\n }\n const childResumeQrl = child.getAttribute('data-fict-h')\n if (childResumeQrl) {\n prefetchQrl(childResumeQrl, ownerDocument)\n }\n })\n}\n\nfunction prefetchQrl(qrl: string, ownerDocument?: Document): void {\n const { url } = parseQrl(qrl)\n if (!url || prefetchedUrls.has(url)) return\n\n prefetchedUrls.add(url)\n\n // Resolve through manifest for production builds\n const resolvedUrl = resolveModuleUrl(url)\n\n // Use modulepreload link for best browser support\n const doc = ownerDocument ?? (typeof document !== 'undefined' ? document : undefined)\n if (doc) {\n const link = doc.createElement('link')\n link.rel = 'modulepreload'\n link.href = resolvedUrl\n link.crossOrigin = 'anonymous'\n doc.head?.appendChild(link)\n }\n}\n\n// ============================================================================\n\n/**\n * Wrapper that tracks the async handler promise for testing.\n */\nfunction handleResumableEvent(event: Event): void {\n const promise = handleResumableEventAsync(event)\n pendingHandlers.add(promise)\n void promise\n .catch(error => {\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error('[fict/loader] Failed to handle resumable event.', error)\n }\n })\n .finally(() => {\n pendingHandlers.delete(promise)\n })\n}\n\nasync function handleResumableEventAsync(event: Event): Promise<void> {\n const path =\n typeof event.composedPath === 'function' ? event.composedPath() : buildEventPath(event)\n\n for (const node of path) {\n if (!(node instanceof Element)) continue\n const qrl = node.getAttribute(`on:${event.type}`)\n if (!qrl) continue\n\n const host = node.closest('[data-fict-s]') as Element | null\n if (!host) continue\n const scopeId = host.getAttribute('data-fict-s')\n if (!scopeId) continue\n\n const snapshot = __fictGetSSRScope(scopeId)\n if (!snapshot) {\n emitSnapshotIssue({\n code: 'scope_snapshot_missing',\n message: `[fict/loader] Missing scope snapshot for ${scopeId}; skipping resumable handler execution.`,\n source: 'event',\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n scopeId,\n })\n continue\n }\n __fictEnsureScope(scopeId, host, snapshot)\n\n const { url, exportName } = parseQrl(qrl)\n\n // Pre-emptively prevent default on navigations/forms while we await modules\n if (event.cancelable && (event.type === 'click' || event.type === 'submit')) {\n const tag = node.tagName.toLowerCase()\n if (tag === 'a' || tag === 'form') {\n event.preventDefault()\n }\n }\n\n // Resume FIRST to set up reactive bindings BEFORE the handler runs\n if (!hydratedScopes.has(scopeId)) {\n const resumeQrl = host.getAttribute('data-fict-h')\n if (resumeQrl) {\n const { url: resumeUrl, exportName: resumeExport } = parseQrl(resumeQrl)\n const resolvedResumeUrl = resolveModuleUrl(resumeUrl)\n // Load the module to ensure resume functions are registered\n await import(/* @vite-ignore */ resolvedResumeUrl)\n // Get resume function from registry (not module exports)\n const resumeFn = __fictGetResume(resumeExport)\n if (typeof resumeFn === 'function') {\n await (resumeFn as (scopeId: string, host: Element) => unknown)(scopeId, host)\n hydratedScopes.add(scopeId)\n }\n }\n }\n\n // THEN run the handler - now signal updates will trigger DOM updates\n const resolvedUrl = resolveModuleUrl(url)\n const mod = await import(/* @vite-ignore */ resolvedUrl)\n const handler = (mod as Record<string, unknown>)[exportName]\n if (typeof handler === 'function') {\n await (handler as (scopeId: string, ev: Event, el: Element) => unknown)(scopeId, event, node)\n }\n\n return\n }\n}\n\nfunction parseQrl(qrl: string): { url: string; exportName: string } {\n const [ref] = qrl.split('[')\n if (!ref) {\n return { url: '', exportName: 'default' }\n }\n const hashIndex = ref.lastIndexOf('#')\n if (hashIndex === -1) {\n return { url: ref, exportName: 'default' }\n }\n return { url: ref.slice(0, hashIndex), exportName: ref.slice(hashIndex + 1) }\n}\n\nfunction buildEventPath(event: Event): EventTarget[] {\n const path: EventTarget[] = []\n let node: EventTarget | null = event.target\n while (node) {\n path.push(node)\n node = (node as Node).parentNode\n }\n path.push(window)\n return path\n}\n\n// Re-export for handler authors (optional)\nexport { __fictUseLexicalScope } from './resume'\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/fict/fict/packages/runtime/dist/loader.cjs","../src/loader.ts"],"names":[],"mappings":"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","file":"/home/runner/work/fict/fict/packages/runtime/dist/loader.cjs","sourcesContent":[null,"import { DelegatedEvents } from './constants'\nimport {\n FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n type SSRState,\n __fictEnableResumable,\n __fictEnsureScope,\n __fictGetResume,\n __fictGetSSRScope,\n __fictMergeSSRState,\n __fictSetSSRState,\n __fictUseLexicalScope,\n} from './resume'\n\n// ============================================================================\n// Module Resolution\n// ============================================================================\n\n/**\n * Resolve a module URL through the manifest if available.\n * In production, virtual module URLs (virtual:fict-handler:...) are mapped\n * to their built chunk URLs through the manifest.\n */\nfunction resolveModuleUrl(url: string): string {\n const manifest = (globalThis as Record<string, unknown>).__FICT_MANIFEST__ as\n | Record<string, string>\n | undefined\n\n if (manifest) {\n // Check if the URL (without #fragment) is in the manifest\n const resolved = manifest[url]\n if (resolved) {\n return resolved\n }\n }\n\n return url\n}\n\nfunction resolveAbsoluteModuleUrl(url: string, ownerDocument?: Document): string {\n const baseUrl =\n ownerDocument?.baseURI ?? (typeof document !== 'undefined' ? document.baseURI : undefined)\n if (!baseUrl) return url\n\n try {\n return new URL(url, baseUrl).href\n } catch {\n return url\n }\n}\n\nfunction normalizeImportUrl(url: string): string {\n if (!url.startsWith('data:')) {\n return url\n }\n\n const dataSeparatorIndex = url.indexOf(',')\n if (dataSeparatorIndex === -1) {\n return url\n }\n\n const metadata = url.slice(0, dataSeparatorIndex)\n const payload = url.slice(dataSeparatorIndex + 1)\n if (metadata.includes(';base64')) {\n return url\n }\n\n try {\n return `${metadata},${encodeURIComponent(decodeURIComponent(payload))}`\n } catch {\n return `${metadata},${encodeURIComponent(payload)}`\n }\n}\n\ninterface PreservedControlState {\n value?: string\n checked?: boolean\n selectedIndex?: number\n selectedValues?: string[]\n}\n\nfunction captureControlState(node: Element, event: Event): PreservedControlState | null {\n if (event.type !== 'input' && event.type !== 'change') return null\n\n if (node instanceof HTMLInputElement) {\n if (node.type === 'file') return null\n if (node.type === 'checkbox' || node.type === 'radio') {\n return { checked: node.checked }\n }\n return { value: node.value }\n }\n\n if (node instanceof HTMLTextAreaElement) {\n return { value: node.value }\n }\n\n if (node instanceof HTMLSelectElement) {\n return node.multiple\n ? {\n selectedValues: Array.from(node.selectedOptions).map(option => option.value),\n }\n : {\n value: node.value,\n selectedIndex: node.selectedIndex,\n }\n }\n\n return null\n}\n\nfunction restoreControlState(node: Element, state: PreservedControlState | null): void {\n if (!state) return\n\n if (node instanceof HTMLInputElement) {\n if (typeof state.checked === 'boolean') {\n node.checked = state.checked\n }\n if (typeof state.value === 'string' && node.type !== 'file') {\n node.value = state.value\n }\n return\n }\n\n if (node instanceof HTMLTextAreaElement) {\n if (typeof state.value === 'string') {\n node.value = state.value\n }\n return\n }\n\n if (node instanceof HTMLSelectElement) {\n if (Array.isArray(state.selectedValues) && node.multiple) {\n const selected = new Set(state.selectedValues)\n for (const option of Array.from(node.options)) {\n option.selected = selected.has(option.value)\n }\n return\n }\n\n if (typeof state.selectedIndex === 'number') {\n node.selectedIndex = state.selectedIndex\n }\n if (typeof state.value === 'string') {\n node.value = state.value\n }\n }\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PrefetchStrategy {\n /**\n * Enable visibility-based prefetch using IntersectionObserver.\n * Prefetches modules when interactive elements come into view.\n * @default true\n */\n visibility?: boolean\n /**\n * Root margin for IntersectionObserver (e.g., '200px' to prefetch earlier).\n * @default '200px'\n */\n visibilityMargin?: string\n /**\n * Enable hover-based prefetch using pointerover events.\n * Prefetches modules when user hovers over interactive elements.\n * @default true\n */\n hover?: boolean\n /**\n * Delay in ms before prefetching on hover (debounce rapid movements).\n * @default 50\n */\n hoverDelay?: number\n}\n\nexport interface ResumableLoaderOptions {\n document?: Document\n snapshotScriptId?: string\n events?: string[]\n /**\n * Receives structured snapshot/resume issues detected by the loader.\n * Useful for telemetry and fail-safe fallback orchestration.\n */\n onSnapshotIssue?: (issue: SnapshotIssue) => void\n /**\n * Prefetch strategy configuration.\n * Set to false to disable all prefetching.\n * @default { visibility: true, hover: true }\n */\n prefetch?: PrefetchStrategy | false\n}\n\nexport type SnapshotIssueCode =\n | 'snapshot_parse_error'\n | 'snapshot_invalid_shape'\n | 'snapshot_unsupported_version'\n | 'scope_snapshot_missing'\n\nexport interface SnapshotIssue {\n code: SnapshotIssueCode\n message: string\n source: string\n expectedVersion: number\n actualVersion?: number\n scopeId?: string\n}\n\n// ============================================================================\n// State\n// ============================================================================\n\nconst hydratedScopes = new Set<string>()\nconst prefetchedUrls = new Set<string>()\nlet prefetchCleanup: (() => void) | null = null\nlet eventListenerCleanup: (() => void) | null = null\nlet snapshotObserver: MutationObserver | null = null\nconst processedSnapshots = new Set<HTMLScriptElement>()\nlet snapshotIssueHandler: ((issue: SnapshotIssue) => void) | null = null\nconst emittedIssueKeys = new Set<string>()\n\n/**\n * Reset the hydrated scopes set. Useful for testing.\n */\nexport function resetHydratedScopes(): void {\n hydratedScopes.clear()\n}\n\n/**\n * Reset the prefetched URLs set. Useful for testing.\n */\nexport function resetPrefetchedUrls(): void {\n prefetchedUrls.clear()\n}\n\n/**\n * Set of pending handler promises. Used for testing to wait for all handlers to complete.\n */\nconst pendingHandlers = new Set<Promise<void>>()\n\n/**\n * Wait for all pending event handlers to complete. Useful for testing.\n */\nexport async function waitForPendingHandlers(): Promise<void> {\n if (pendingHandlers.size === 0) return\n await Promise.allSettled([...pendingHandlers])\n}\n\n/**\n * Clean up all registered event listeners. Useful for testing.\n */\nexport function cleanupEventListeners(): void {\n if (eventListenerCleanup) {\n eventListenerCleanup()\n eventListenerCleanup = null\n }\n}\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\nexport function installResumableLoader(options: ResumableLoaderOptions = {}): void {\n const doc = options.document ?? window.document\n const scriptId = options.snapshotScriptId ?? '__FICT_SNAPSHOT__'\n snapshotIssueHandler = options.onSnapshotIssue ?? null\n\n // Reset hydrated scopes for fresh loader installation\n hydratedScopes.clear()\n prefetchedUrls.clear()\n processedSnapshots.clear()\n emittedIssueKeys.clear()\n __fictSetSSRState(null)\n\n // Clean up previous event listeners\n if (eventListenerCleanup) {\n eventListenerCleanup()\n eventListenerCleanup = null\n }\n\n // Clean up previous prefetch handlers\n if (prefetchCleanup) {\n prefetchCleanup()\n prefetchCleanup = null\n }\n\n if (snapshotObserver) {\n snapshotObserver.disconnect()\n snapshotObserver = null\n }\n\n const snapshotEl = doc.getElementById(scriptId)\n if (snapshotEl?.textContent) {\n const state = parseSnapshotText(snapshotEl.textContent, `#${scriptId}`)\n if (state) {\n __fictSetSSRState(state)\n }\n }\n\n const snapshotScripts = doc.querySelectorAll(\n 'script[type=\"application/json\"][data-fict-snapshot]',\n )\n for (const script of Array.from(snapshotScripts)) {\n parseSnapshotScript(script as HTMLScriptElement)\n }\n\n if (typeof MutationObserver !== 'undefined') {\n snapshotObserver = new MutationObserver(mutations => {\n for (const mutation of mutations) {\n for (const node of Array.from(mutation.addedNodes)) {\n if (!(node instanceof Element)) continue\n if (node.tagName === 'SCRIPT') {\n const script = node as HTMLScriptElement\n if (isSnapshotScript(script)) {\n parseSnapshotScript(script)\n }\n }\n const nested = node.querySelectorAll?.(\n 'script[type=\"application/json\"][data-fict-snapshot]',\n )\n if (nested && nested.length) {\n for (const script of Array.from(nested)) {\n parseSnapshotScript(script as HTMLScriptElement)\n }\n }\n }\n }\n })\n snapshotObserver.observe(doc.documentElement ?? doc, { childList: true, subtree: true })\n }\n\n __fictEnableResumable()\n\n const events = options.events ?? Array.from(DelegatedEvents)\n for (const eventName of events) {\n doc.addEventListener(eventName, handleResumableEvent, true)\n }\n\n // Store cleanup function for event listeners\n eventListenerCleanup = () => {\n for (const eventName of events) {\n doc.removeEventListener(eventName, handleResumableEvent, true)\n }\n }\n\n // Setup prefetch if enabled\n if (options.prefetch !== false) {\n prefetchCleanup = setupPrefetch(doc, options.prefetch ?? {})\n }\n}\n\nfunction isSnapshotScript(script: HTMLScriptElement): boolean {\n return script.type === 'application/json' && script.hasAttribute('data-fict-snapshot')\n}\n\nfunction parseSnapshotScript(script: HTMLScriptElement): void {\n if (processedSnapshots.has(script)) return\n processedSnapshots.add(script)\n const text = script.textContent\n if (!text) return\n const source = script.id ? `#${script.id}` : '<script[data-fict-snapshot]>'\n const state = parseSnapshotText(text, source)\n if (state) {\n __fictMergeSSRState(state)\n }\n}\n\nfunction parseSnapshotText(text: string, source: string): SSRState | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n emitSnapshotIssue({\n code: 'snapshot_parse_error',\n message: '[fict/loader] Failed to parse SSR snapshot JSON.',\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n })\n return null\n }\n\n return normalizeSnapshotState(parsed, source)\n}\n\nfunction normalizeSnapshotState(value: unknown, source: string): SSRState | null {\n if (!isRecord(value)) {\n emitSnapshotIssue({\n code: 'snapshot_invalid_shape',\n message: '[fict/loader] Snapshot payload must be an object.',\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n })\n return null\n }\n\n const rawVersion = value.v\n const version = rawVersion === undefined ? FICT_SSR_SNAPSHOT_SCHEMA_VERSION : rawVersion\n if (!Number.isInteger(version) || version !== FICT_SSR_SNAPSHOT_SCHEMA_VERSION) {\n const versionIssue: SnapshotIssue = {\n code: 'snapshot_unsupported_version',\n message: `[fict/loader] Snapshot schema version ${String(version)} is not supported by this runtime.`,\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n }\n if (typeof version === 'number') {\n versionIssue.actualVersion = version\n }\n emitSnapshotIssue({\n ...versionIssue,\n })\n return null\n }\n\n const scopes = value.scopes\n if (!isRecord(scopes)) {\n emitSnapshotIssue({\n code: 'snapshot_invalid_shape',\n message: '[fict/loader] Snapshot payload is missing a valid `scopes` object.',\n source,\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n })\n return null\n }\n\n return { v: FICT_SSR_SNAPSHOT_SCHEMA_VERSION, scopes: scopes as SSRState['scopes'] }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction emitSnapshotIssue(issue: SnapshotIssue): void {\n const key =\n `${issue.code}|${issue.source}|${issue.scopeId ?? ''}|` +\n `${issue.actualVersion ?? ''}|${issue.expectedVersion}`\n if (emittedIssueKeys.has(key)) return\n emittedIssueKeys.add(key)\n\n snapshotIssueHandler?.(issue)\n\n if (typeof console !== 'undefined' && typeof console.warn === 'function') {\n console.warn(issue.message)\n }\n}\n\n// ============================================================================\n// Prefetch Implementation\n// ============================================================================\n\nfunction setupPrefetch(doc: Document, strategy: PrefetchStrategy): () => void {\n const cleanupFns: (() => void)[] = []\n\n // Visibility-based prefetch\n if (strategy.visibility !== false) {\n const cleanup = setupVisibilityPrefetch(doc, strategy.visibilityMargin ?? '200px')\n cleanupFns.push(cleanup)\n }\n\n // Hover-based prefetch\n if (strategy.hover !== false) {\n const cleanup = setupHoverPrefetch(doc, strategy.hoverDelay ?? 50)\n cleanupFns.push(cleanup)\n }\n\n return () => {\n for (const cleanup of cleanupFns) {\n cleanup()\n }\n }\n}\n\nfunction setupVisibilityPrefetch(doc: Document, rootMargin: string): () => void {\n // Check if IntersectionObserver is available\n if (typeof IntersectionObserver === 'undefined') {\n return () => {}\n }\n\n const observer = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const el = entry.target as Element\n prefetchElementQrls(el)\n // Stop observing after prefetch\n observer.unobserve(el)\n }\n }\n },\n { rootMargin },\n )\n\n // Observe all elements with on:* attributes\n const interactiveElements = doc.querySelectorAll(\n '[on\\\\:click], [on\\\\:input], [on\\\\:change], [on\\\\:submit], [on\\\\:keydown], [on\\\\:keyup]',\n )\n interactiveElements.forEach(el => observer.observe(el))\n\n // Also observe elements with data-fict-h (resumable components)\n const resumableHosts = doc.querySelectorAll('[data-fict-h]')\n resumableHosts.forEach(el => observer.observe(el))\n\n return () => {\n observer.disconnect()\n }\n}\n\nfunction setupHoverPrefetch(doc: Document, delay: number): () => void {\n let hoverTimeout: ReturnType<typeof setTimeout> | null = null\n let lastHoveredElement: Element | null = null\n\n const handlePointerOver = (event: Event) => {\n const target = event.target\n if (!(target instanceof Element)) return\n\n // Find the closest element with interactive attributes\n const interactiveEl =\n target.closest('[on\\\\:click]') ||\n target.closest('[on\\\\:input]') ||\n target.closest('[on\\\\:change]') ||\n target.closest('[on\\\\:submit]') ||\n target.closest('[data-fict-h]')\n\n if (!interactiveEl || interactiveEl === lastHoveredElement) return\n\n lastHoveredElement = interactiveEl\n\n // Clear previous timeout\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n }\n\n // Debounce prefetch\n hoverTimeout = setTimeout(() => {\n prefetchElementQrls(interactiveEl)\n }, delay)\n }\n\n const handlePointerOut = () => {\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n hoverTimeout = null\n }\n lastHoveredElement = null\n }\n\n doc.addEventListener('pointerover', handlePointerOver, { passive: true })\n doc.addEventListener('pointerout', handlePointerOut, { passive: true })\n\n return () => {\n doc.removeEventListener('pointerover', handlePointerOver)\n doc.removeEventListener('pointerout', handlePointerOut)\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n }\n }\n}\n\nfunction prefetchElementQrls(el: Element): void {\n const ownerDocument = el.ownerDocument ?? (typeof document !== 'undefined' ? document : undefined)\n // Prefetch event handler QRLs\n const eventAttrs = ['on:click', 'on:input', 'on:change', 'on:submit', 'on:keydown', 'on:keyup']\n for (const attr of eventAttrs) {\n const qrl = el.getAttribute(attr)\n if (qrl) {\n prefetchQrl(qrl, ownerDocument)\n }\n }\n\n // Prefetch resume handler QRL\n const resumeQrl = el.getAttribute('data-fict-h')\n if (resumeQrl) {\n prefetchQrl(resumeQrl, ownerDocument)\n }\n\n // Also check children for nested QRLs\n const children = el.querySelectorAll(\n '[on\\\\:click], [on\\\\:input], [on\\\\:change], [on\\\\:submit], [data-fict-h]',\n )\n children.forEach(child => {\n for (const attr of eventAttrs) {\n const qrl = child.getAttribute(attr)\n if (qrl) {\n prefetchQrl(qrl, ownerDocument)\n }\n }\n const childResumeQrl = child.getAttribute('data-fict-h')\n if (childResumeQrl) {\n prefetchQrl(childResumeQrl, ownerDocument)\n }\n })\n}\n\nfunction prefetchQrl(qrl: string, ownerDocument?: Document): void {\n const { url } = parseQrl(qrl)\n if (!url || prefetchedUrls.has(url)) return\n\n prefetchedUrls.add(url)\n\n // Resolve through manifest for production builds\n const resolvedUrl = resolveModuleUrl(url)\n\n // Use modulepreload link for best browser support\n const doc = ownerDocument ?? (typeof document !== 'undefined' ? document : undefined)\n if (doc) {\n const link = doc.createElement('link')\n link.rel = 'modulepreload'\n link.href = resolvedUrl\n link.crossOrigin = 'anonymous'\n doc.head?.appendChild(link)\n }\n}\n\n// ============================================================================\n\n/**\n * Wrapper that tracks the async handler promise for testing.\n */\nfunction handleResumableEvent(event: Event): void {\n const promise = handleResumableEventAsync(event)\n pendingHandlers.add(promise)\n void promise\n .catch(error => {\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error('[fict/loader] Failed to handle resumable event.', error)\n }\n })\n .finally(() => {\n pendingHandlers.delete(promise)\n })\n}\n\nasync function handleResumableEventAsync(event: Event): Promise<void> {\n const path =\n typeof event.composedPath === 'function' ? event.composedPath() : buildEventPath(event)\n\n for (const node of path) {\n if (!(node instanceof Element)) continue\n const qrl = node.getAttribute(`on:${event.type}`)\n if (!qrl) continue\n\n const host = node.closest('[data-fict-s]') as Element | null\n if (!host) continue\n const scopeId = host.getAttribute('data-fict-s')\n if (!scopeId) continue\n\n const snapshot = __fictGetSSRScope(scopeId)\n if (!snapshot) {\n emitSnapshotIssue({\n code: 'scope_snapshot_missing',\n message: `[fict/loader] Missing scope snapshot for ${scopeId}; skipping resumable handler execution.`,\n source: 'event',\n expectedVersion: FICT_SSR_SNAPSHOT_SCHEMA_VERSION,\n scopeId,\n })\n continue\n }\n __fictEnsureScope(scopeId, host, snapshot)\n\n const { url, exportName } = parseQrl(qrl)\n\n // Pre-emptively prevent default on navigations/forms while we await modules\n if (event.cancelable && (event.type === 'click' || event.type === 'submit')) {\n const tag = node.tagName.toLowerCase()\n if (tag === 'a' || tag === 'form') {\n event.preventDefault()\n }\n }\n\n const preservedControlState = captureControlState(node, event)\n let resumedDuringEvent = false\n\n // Resume FIRST to set up reactive bindings BEFORE the handler runs\n if (!hydratedScopes.has(scopeId)) {\n const resumeQrl = host.getAttribute('data-fict-h')\n if (resumeQrl) {\n const { url: resumeUrl, exportName: resumeExport } = parseQrl(resumeQrl)\n const resolvedResumeUrl = resolveModuleUrl(resumeUrl)\n const resolvedAbsoluteResumeUrl = resolveAbsoluteModuleUrl(\n resolvedResumeUrl,\n host.ownerDocument ?? undefined,\n )\n const resolvedResumeQrl = `${resolvedResumeUrl}#${resumeExport}`\n const resolvedAbsoluteResumeQrl = `${resolvedAbsoluteResumeUrl}#${resumeExport}`\n const normalizedResumeImportUrl = normalizeImportUrl(resolvedResumeUrl)\n // Load the module to ensure resume functions are registered\n await import(/* @vite-ignore */ normalizedResumeImportUrl)\n // Get resume function from registry (not module exports)\n const resumeFn =\n __fictGetResume(resumeQrl) ??\n __fictGetResume(resolvedResumeQrl) ??\n __fictGetResume(resolvedAbsoluteResumeQrl) ??\n __fictGetResume(resumeExport)\n if (typeof resumeFn === 'function') {\n await (resumeFn as (scopeId: string, host: Element) => unknown)(scopeId, host)\n hydratedScopes.add(scopeId)\n resumedDuringEvent = true\n }\n }\n }\n\n if (resumedDuringEvent) {\n restoreControlState(node, preservedControlState)\n }\n\n // THEN run the handler - now signal updates will trigger DOM updates\n const resolvedUrl = resolveModuleUrl(url)\n const normalizedImportUrl = normalizeImportUrl(resolvedUrl)\n const mod = await import(/* @vite-ignore */ normalizedImportUrl)\n const handler = (mod as Record<string, unknown>)[exportName]\n if (typeof handler === 'function') {\n const originalCurrentTarget = event.currentTarget\n Object.defineProperty(event, 'currentTarget', {\n configurable: true,\n get() {\n return node\n },\n })\n try {\n await (handler as (scopeId: string, ev: Event, el: Element) => unknown)(\n scopeId,\n event,\n node,\n )\n } finally {\n Object.defineProperty(event, 'currentTarget', {\n configurable: true,\n get() {\n return originalCurrentTarget\n },\n })\n }\n }\n\n return\n }\n}\n\nfunction parseQrl(qrl: string): { url: string; exportName: string } {\n const [ref] = qrl.split('[')\n if (!ref) {\n return { url: '', exportName: 'default' }\n }\n const hashIndex = ref.lastIndexOf('#')\n if (hashIndex === -1) {\n return { url: ref, exportName: 'default' }\n }\n return { url: ref.slice(0, hashIndex), exportName: ref.slice(hashIndex + 1) }\n}\n\nfunction buildEventPath(event: Event): EventTarget[] {\n const path: EventTarget[] = []\n let node: EventTarget | null = event.target\n while (node) {\n path.push(node)\n node = (node as Node).parentNode\n }\n path.push(window)\n return path\n}\n\n// Re-export for handler authors (optional)\nexport { __fictUseLexicalScope } from './resume'\n"]}
|
package/dist/loader.d.cts
CHANGED
package/dist/loader.d.ts
CHANGED