@takazudo/zfb 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +8 -7
  2. package/dist/config.d.ts +43 -9
  3. package/dist/config.js +23 -12
  4. package/dist/config.js.map +1 -1
  5. package/dist/content.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/island-boundary.d.ts +2 -2
  9. package/dist/island-boundary.js +4 -2
  10. package/dist/island-boundary.js.map +1 -1
  11. package/dist/island.d.ts +8 -4
  12. package/dist/island.js +1 -1
  13. package/dist/island.js.map +1 -1
  14. package/dist/jsx-types.d.ts +1 -1
  15. package/dist/jsx-types.js.map +1 -1
  16. package/dist/runtime.d.ts +7 -4
  17. package/dist/runtime.js +166 -28
  18. package/dist/runtime.js.map +1 -1
  19. package/dist/slugify.js.map +1 -1
  20. package/dist/zudo-react/description.d.ts +18 -0
  21. package/dist/zudo-react/description.js +41 -0
  22. package/dist/zudo-react/description.js.map +1 -1
  23. package/dist/zudo-react/dom-bindings.d.ts +2 -1
  24. package/dist/zudo-react/dom-bindings.js +16 -22
  25. package/dist/zudo-react/dom-bindings.js.map +1 -1
  26. package/dist/zudo-react/forms.js.map +1 -1
  27. package/dist/zudo-react/hydrate.js +27 -34
  28. package/dist/zudo-react/hydrate.js.map +1 -1
  29. package/dist/zudo-react/index.d.ts +2 -1
  30. package/dist/zudo-react/index.js.map +1 -1
  31. package/dist/zudo-react/jsx-dev-runtime.d.ts +2 -6
  32. package/dist/zudo-react/jsx-dev-runtime.js +3 -3
  33. package/dist/zudo-react/jsx-dev-runtime.js.map +1 -1
  34. package/dist/zudo-react/jsx-runtime.js +2 -2
  35. package/dist/zudo-react/jsx-runtime.js.map +1 -1
  36. package/dist/zudo-react/jsx-types.d.ts +80 -31
  37. package/dist/zudo-react/jsx-types.js.map +1 -1
  38. package/dist/zudo-react/props-transport.d.ts +2 -0
  39. package/dist/zudo-react/props-transport.js +42 -14
  40. package/dist/zudo-react/props-transport.js.map +1 -1
  41. package/dist/zudo-react/raw-html.d.ts +1 -0
  42. package/dist/zudo-react/raw-html.js +120 -0
  43. package/dist/zudo-react/raw-html.js.map +1 -0
  44. package/dist/zudo-react/reactive.js.map +1 -1
  45. package/dist/zudo-react/render-html.d.ts +11 -1
  46. package/dist/zudo-react/render-html.js +96 -71
  47. package/dist/zudo-react/render-html.js.map +1 -1
  48. package/dist/zudo-react/root.js +24 -1
  49. package/dist/zudo-react/root.js.map +1 -1
  50. package/dist/zudo-react/server.d.ts +2 -0
  51. package/dist/zudo-react/server.js.map +1 -1
  52. package/dist/zudo-react/structure.d.ts +2 -0
  53. package/dist/zudo-react/structure.js +14 -0
  54. package/dist/zudo-react/structure.js.map +1 -1
  55. package/dist/zudo-react/style.d.ts +10 -0
  56. package/dist/zudo-react/style.js +525 -0
  57. package/dist/zudo-react/style.js.map +1 -0
  58. package/dist/zudo-react/testing.d.ts +27 -0
  59. package/dist/zudo-react/testing.js +117 -0
  60. package/dist/zudo-react/testing.js.map +1 -0
  61. package/dist/zudo-react/vocabulary.d.ts +19 -0
  62. package/dist/zudo-react/vocabulary.js +155 -0
  63. package/dist/zudo-react/vocabulary.js.map +1 -0
  64. package/package.json +16 -10
@@ -1,4 +1,6 @@
1
- import type { Child, Component, Key } from "./description.js";
1
+ import type { CSSProperties } from "./style.js";
2
+ export type { CSSProperties, CssProperty } from "./style.js";
3
+ import type { Child, Component, Description, Key } from "./description.js";
2
4
  import type { Listener, Ref } from "./index.js";
3
5
  import type { ReadonlySignal, Signal } from "./reactive-types.js";
4
6
  type Value<T> = T | ReadonlySignal<T> | undefined;
@@ -6,10 +8,13 @@ type ScalarAttribute = Value<string | number | boolean | null>;
6
8
  type DimensionAttribute = Value<string | number | null>;
7
9
  type StringAttribute = Value<string | null>;
8
10
  type BooleanAttribute = Value<boolean | null>;
9
- type CssProperty = `--${string}` | `${string}-${string}` | "color" | "display" | "opacity" | "width" | "height" | "margin" | "padding" | "border" | "background" | "position" | "top" | "right" | "bottom" | "left" | "overflow" | "transform" | "transition" | "animation" | "font" | "flex" | "grid" | "gap";
10
- type CssStyle = Readonly<Partial<Record<CssProperty, string | number | null | undefined>>>;
11
- type EventProps = {
12
- [name: `on:${string}`]: Listener | undefined;
11
+ type AnyListener = Listener<any>;
12
+ type EventProps<TEl extends Element, TMap extends Record<keyof TMap, Event>> = {
13
+ [K in keyof TMap & string as `on:${K}` | `on:${K}:capture`]?: Listener<TMap[K] & {
14
+ currentTarget: TEl;
15
+ }>;
16
+ } & {
17
+ [name: `on:${string}`]: AnyListener | undefined;
13
18
  };
14
19
  type DataAria = {
15
20
  [name: `data-${string}`]: ScalarAttribute;
@@ -30,12 +35,12 @@ interface CommonAttributes<T extends Element = Element> extends ReservedProps<T>
30
35
  dir?: StringAttribute;
31
36
  slot?: StringAttribute;
32
37
  role?: StringAttribute;
33
- style?: Value<string | CssStyle | null>;
38
+ style?: Value<string | CSSProperties | null>;
34
39
  hidden?: BooleanAttribute;
35
40
  inert?: BooleanAttribute;
36
- contenteditable?: StringAttribute;
37
- draggable?: StringAttribute;
38
- spellcheck?: StringAttribute;
41
+ contenteditable?: Value<string | boolean | null>;
42
+ draggable?: Value<string | boolean | null>;
43
+ spellcheck?: Value<string | boolean | null>;
39
44
  tabindex?: Value<number | null>;
40
45
  accesskey?: StringAttribute;
41
46
  translate?: StringAttribute;
@@ -43,18 +48,39 @@ interface CommonAttributes<T extends Element = Element> extends ReservedProps<T>
43
48
  onload?: string | undefined;
44
49
  onerror?: string | undefined;
45
50
  }
46
- interface HtmlAttributes<T extends Element = HTMLElement> extends CommonAttributes<T> {
51
+ interface HtmlBaseAttributes<T extends HTMLElement = HTMLElement> extends CommonAttributes<T> {
47
52
  href?: StringAttribute;
48
53
  target?: StringAttribute;
49
54
  rel?: StringAttribute;
50
- download?: StringAttribute;
55
+ download?: Value<string | boolean | null>;
56
+ property?: StringAttribute;
57
+ itemprop?: StringAttribute;
58
+ hreflang?: StringAttribute;
59
+ as?: StringAttribute;
60
+ integrity?: StringAttribute;
61
+ async?: BooleanAttribute;
62
+ defer?: BooleanAttribute;
63
+ nonce?: StringAttribute;
64
+ popover?: StringAttribute;
65
+ popovertarget?: StringAttribute;
66
+ popovertargetaction?: StringAttribute;
67
+ srcdoc?: StringAttribute;
68
+ fetchpriority?: StringAttribute;
69
+ inputmode?: StringAttribute;
70
+ autocapitalize?: StringAttribute;
71
+ form?: StringAttribute;
72
+ label?: StringAttribute;
73
+ preload?: StringAttribute;
74
+ playsinline?: BooleanAttribute;
75
+ wrap?: StringAttribute;
76
+ closedby?: StringAttribute;
51
77
  src?: StringAttribute;
52
78
  alt?: StringAttribute;
53
79
  width?: Value<string | number | null>;
54
80
  height?: Value<string | number | null>;
55
81
  type?: StringAttribute;
56
82
  name?: StringAttribute;
57
- value?: ScalarAttribute;
83
+ value?: string | number | null | undefined;
58
84
  placeholder?: StringAttribute;
59
85
  for?: StringAttribute;
60
86
  charset?: StringAttribute;
@@ -63,9 +89,10 @@ interface HtmlAttributes<T extends Element = HTMLElement> extends CommonAttribut
63
89
  autofocus?: BooleanAttribute;
64
90
  required?: BooleanAttribute;
65
91
  disabled?: BooleanAttribute;
66
- checked?: BooleanAttribute;
92
+ checked?: boolean | null | undefined;
67
93
  selected?: BooleanAttribute;
68
94
  multiple?: BooleanAttribute;
95
+ reversed?: BooleanAttribute;
69
96
  open?: BooleanAttribute;
70
97
  controls?: BooleanAttribute;
71
98
  muted?: BooleanAttribute;
@@ -78,6 +105,7 @@ interface HtmlAttributes<T extends Element = HTMLElement> extends CommonAttribut
78
105
  min?: StringAttribute;
79
106
  max?: StringAttribute;
80
107
  step?: StringAttribute;
108
+ start?: Value<string | number | null>;
81
109
  pattern?: StringAttribute;
82
110
  autocomplete?: StringAttribute;
83
111
  accept?: StringAttribute;
@@ -105,39 +133,47 @@ interface HtmlAttributes<T extends Element = HTMLElement> extends CommonAttribut
105
133
  allow?: StringAttribute;
106
134
  allowfullscreen?: BooleanAttribute;
107
135
  }
108
- type HtmlProps<T extends Element = HTMLElement> = HtmlAttributes<T> & DataAria & EventProps;
109
- type InputBase = Omit<HtmlProps<HTMLInputElement>, "type"> & {
136
+ export type HTMLAttributes<T extends HTMLElement = HTMLElement> = HtmlBaseAttributes<T> & DataAria & EventProps<T, HTMLElementEventMap>;
137
+ type RawTextProps<T extends HTMLElement = HTMLElement> = Omit<HtmlBaseAttributes<T>, "children" | "rawHtml"> & DataAria & EventProps<T, HTMLElementEventMap> & {
138
+ children?: never;
139
+ rawHtml?: string | undefined;
140
+ };
141
+ type IframeProps = Omit<HtmlBaseAttributes<HTMLIFrameElement>, "children" | "rawHtml"> & DataAria & EventProps<HTMLIFrameElement, HTMLElementEventMap> & {
142
+ children?: never;
143
+ rawHtml?: never;
144
+ };
145
+ type InputBase = Omit<HtmlBaseAttributes<HTMLInputElement>, "type"> & DataAria & EventProps<HTMLInputElement, HTMLElementEventMap> & {
110
146
  defaultValue?: string | undefined;
111
147
  defaultChecked?: boolean | undefined;
112
148
  };
113
- type InputProps = (InputBase & {
149
+ export type InputProps = InputBase & ({
114
150
  type?: "text" | "search" | "email" | "url" | "tel" | "password" | undefined;
115
151
  modelValue?: Signal<string> | undefined;
116
152
  modelChecked?: never;
117
- }) | (InputBase & {
153
+ } | {
118
154
  type: "checkbox";
119
155
  modelChecked?: Signal<boolean> | undefined;
120
156
  modelValue?: never;
121
- }) | (InputBase & {
157
+ } | {
122
158
  type: "radio";
123
159
  name: string;
124
160
  value: string;
125
161
  modelValue?: Signal<string | null> | undefined;
126
162
  modelChecked?: never;
127
- }) | (InputBase & {
163
+ } | {
128
164
  type: string;
129
165
  modelValue?: never;
130
166
  modelChecked?: never;
131
167
  });
132
- type TextareaProps = HtmlProps<HTMLTextAreaElement> & {
168
+ export type TextareaProps = HTMLAttributes<HTMLTextAreaElement> & {
133
169
  modelValue?: Signal<string> | undefined;
134
170
  defaultValue?: string | undefined;
135
171
  };
136
- type SelectProps = HtmlProps<HTMLSelectElement> & {
172
+ export type SelectProps = HTMLAttributes<HTMLSelectElement> & {
137
173
  modelValue?: Signal<string> | undefined;
138
174
  defaultValue?: string | undefined;
139
175
  };
140
- interface SvgAttributes extends CommonAttributes<SVGElement> {
176
+ interface SvgBaseAttributes<T extends SVGElement = SVGElement> extends CommonAttributes<T> {
141
177
  width?: DimensionAttribute;
142
178
  height?: DimensionAttribute;
143
179
  viewBox?: StringAttribute;
@@ -150,6 +186,10 @@ interface SvgAttributes extends CommonAttributes<SVGElement> {
150
186
  refY?: ScalarAttribute;
151
187
  "xlink:href"?: StringAttribute;
152
188
  "xml:lang"?: StringAttribute;
189
+ xmlns?: StringAttribute;
190
+ "xmlns:xlink"?: StringAttribute;
191
+ href?: StringAttribute;
192
+ focusable?: StringAttribute;
153
193
  "stroke-width"?: ScalarAttribute;
154
194
  "fill-rule"?: StringAttribute;
155
195
  "clip-rule"?: StringAttribute;
@@ -157,6 +197,9 @@ interface SvgAttributes extends CommonAttributes<SVGElement> {
157
197
  "stroke-linejoin"?: StringAttribute;
158
198
  "stop-color"?: StringAttribute;
159
199
  "stop-opacity"?: ScalarAttribute;
200
+ "fill-opacity"?: ScalarAttribute;
201
+ "stroke-dasharray"?: StringAttribute;
202
+ "text-anchor"?: StringAttribute;
160
203
  fill?: StringAttribute;
161
204
  stroke?: StringAttribute;
162
205
  d?: StringAttribute;
@@ -177,19 +220,26 @@ interface SvgAttributes extends CommonAttributes<SVGElement> {
177
220
  offset?: ScalarAttribute;
178
221
  id?: StringAttribute;
179
222
  }
180
- type SvgProps = SvgAttributes & DataAria & EventProps;
181
- type CustomProps = ReservedProps & EventProps & {
182
- [attribute: string]: StringAttribute | Child | Ref<Element> | Listener | undefined;
223
+ export type SVGAttributes<T extends SVGElement = SVGElement> = SvgBaseAttributes<T> & DataAria & EventProps<T, SVGElementEventMap>;
224
+ type CustomProps = ReservedProps & EventProps<HTMLElement, GlobalEventHandlersEventMap> & {
225
+ value?: string | null | undefined;
226
+ checked?: null | undefined;
227
+ [attribute: string]: StringAttribute | Child | Ref<Element> | AnyListener | undefined;
183
228
  };
184
- type HtmlTag = "html" | "head" | "body" | "title" | "base" | "link" | "meta" | "style" | "script" | "div" | "span" | "p" | "a" | "br" | "hr" | "main" | "header" | "footer" | "nav" | "section" | "article" | "aside" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "dl" | "dt" | "dd" | "blockquote" | "pre" | "code" | "strong" | "em" | "b" | "i" | "small" | "mark" | "time" | "figure" | "figcaption" | "img" | "picture" | "source" | "video" | "audio" | "track" | "canvas" | "form" | "label" | "input" | "button" | "textarea" | "select" | "option" | "optgroup" | "fieldset" | "legend" | "output" | "progress" | "meter" | "datalist" | "table" | "caption" | "thead" | "tbody" | "tfoot" | "tr" | "th" | "td" | "col" | "colgroup" | "details" | "summary" | "dialog" | "template" | "slot" | "iframe" | "noscript" | "address" | "abbr" | "bdi" | "bdo" | "cite" | "data" | "del" | "dfn" | "ins" | "kbd" | "map" | "area" | "object" | "param" | "q" | "rp" | "rt" | "ruby" | "s" | "samp" | "sub" | "sup" | "u" | "var" | "wbr" | "embed";
185
- type SvgTag = "svg" | "g" | "path" | "circle" | "ellipse" | "rect" | "line" | "polyline" | "polygon" | "text" | "tspan" | "defs" | "symbol" | "use" | "clipPath" | "mask" | "linearGradient" | "radialGradient" | "stop" | "desc" | "foreignObject";
229
+ type HtmlTag = "html" | "head" | "body" | "title" | "base" | "link" | "meta" | "style" | "script" | "div" | "span" | "p" | "a" | "br" | "hr" | "main" | "header" | "footer" | "nav" | "section" | "article" | "aside" | "search" | "hgroup" | "menu" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "dl" | "dt" | "dd" | "blockquote" | "pre" | "code" | "strong" | "em" | "b" | "i" | "small" | "mark" | "time" | "figure" | "figcaption" | "img" | "picture" | "source" | "video" | "audio" | "track" | "canvas" | "form" | "label" | "input" | "button" | "textarea" | "select" | "option" | "optgroup" | "fieldset" | "legend" | "output" | "progress" | "meter" | "datalist" | "table" | "caption" | "thead" | "tbody" | "tfoot" | "tr" | "th" | "td" | "col" | "colgroup" | "details" | "summary" | "dialog" | "template" | "slot" | "iframe" | "noscript" | "address" | "abbr" | "bdi" | "bdo" | "cite" | "data" | "del" | "dfn" | "ins" | "kbd" | "map" | "area" | "object" | "param" | "q" | "rp" | "rt" | "ruby" | "s" | "samp" | "sub" | "sup" | "u" | "var" | "wbr" | "embed";
230
+ type SvgTag = "svg" | "g" | "path" | "circle" | "ellipse" | "rect" | "line" | "polyline" | "polygon" | "text" | "tspan" | "defs" | "symbol" | "use" | "clipPath" | "mask" | "linearGradient" | "radialGradient" | "stop" | "desc" | "foreignObject" | "pattern" | "filter" | "marker" | "image";
231
+ /** DOM element corresponding to an owned intrinsic tag. */
232
+ export type ElementForTag<Tag extends HtmlTag | SvgTag> = Tag extends HtmlTag ? Tag extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[Tag] : HTMLElement : Tag extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[Tag] : SVGElement;
186
233
  export declare namespace JSX {
187
- type Element = Child;
234
+ type Element = Description;
235
+ type HTMLAttributes<T extends HTMLElement = HTMLElement> = import("./jsx-types.js").HTMLAttributes<T>;
236
+ type SVGAttributes<T extends SVGElement = SVGElement> = import("./jsx-types.js").SVGAttributes<T>;
237
+ type CSSProperties = import("./jsx-types.js").CSSProperties;
188
238
  type ElementType = string | Component<any> | typeof import("../island.js").Island | typeof import("./description.js").Fragment;
189
239
  type IntrinsicElements = {
190
- [K in HtmlTag]: K extends "input" ? InputProps : K extends "textarea" ? TextareaProps : K extends "select" ? SelectProps : HtmlProps;
240
+ [K in HtmlTag]: K extends "input" ? InputProps : K extends "textarea" ? TextareaProps : K extends "select" ? SelectProps : K extends "iframe" ? IframeProps : K extends "script" | "style" ? RawTextProps<ElementForTag<K>> : HTMLAttributes<ElementForTag<K>>;
191
241
  } & {
192
- [K in SvgTag]: SvgProps;
242
+ [K in SvgTag]: SVGAttributes<ElementForTag<K>>;
193
243
  } & {
194
244
  [K in `${string}-${string}`]: CustomProps;
195
245
  };
@@ -200,4 +250,3 @@ export declare namespace JSX {
200
250
  children: unknown;
201
251
  }
202
252
  }
203
- export {};
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-types.js","sourceRoot":"","sources":["../../src/zudo-react/jsx-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Child, Component, Key } from \"./description.js\";\nimport type { Listener, Ref } from \"./index.js\";\nimport type { ReadonlySignal, Signal } from \"./reactive-types.js\";\n\ntype Value<T> = T | ReadonlySignal<T> | undefined;\ntype ScalarAttribute = Value<string | number | boolean | null>;\ntype DimensionAttribute = Value<string | number | null>;\ntype StringAttribute = Value<string | null>;\ntype BooleanAttribute = Value<boolean | null>;\ntype CssProperty =\n | `--${string}`\n | `${string}-${string}`\n | \"color\"\n | \"display\"\n | \"opacity\"\n | \"width\"\n | \"height\"\n | \"margin\"\n | \"padding\"\n | \"border\"\n | \"background\"\n | \"position\"\n | \"top\"\n | \"right\"\n | \"bottom\"\n | \"left\"\n | \"overflow\"\n | \"transform\"\n | \"transition\"\n | \"animation\"\n | \"font\"\n | \"flex\"\n | \"grid\"\n | \"gap\";\ntype CssStyle = Readonly<Partial<Record<CssProperty, string | number | null | undefined>>>;\ntype EventProps = {\n [name: `on:${string}`]: Listener | undefined;\n};\ntype DataAria = {\n [name: `data-${string}`]: ScalarAttribute;\n} & {\n [name: `aria-${string}`]: ScalarAttribute;\n};\n\ninterface ReservedProps<T extends Element = Element> {\n children?: Child | undefined;\n key?: Key | undefined;\n ref?: Ref<T> | undefined;\n rawHtml?: Value<string | null>;\n}\n\ninterface CommonAttributes<T extends Element = Element> extends ReservedProps<T> {\n id?: StringAttribute;\n class?: StringAttribute;\n title?: StringAttribute;\n lang?: StringAttribute;\n dir?: StringAttribute;\n slot?: StringAttribute;\n role?: StringAttribute;\n style?: Value<string | CssStyle | null>;\n hidden?: BooleanAttribute;\n inert?: BooleanAttribute;\n contenteditable?: StringAttribute;\n draggable?: StringAttribute;\n spellcheck?: StringAttribute;\n tabindex?: Value<number | null>;\n accesskey?: StringAttribute;\n translate?: StringAttribute;\n onclick?: string | undefined;\n onload?: string | undefined;\n onerror?: string | undefined;\n}\n\ninterface HtmlAttributes<T extends Element = HTMLElement> extends CommonAttributes<T> {\n href?: StringAttribute;\n target?: StringAttribute;\n rel?: StringAttribute;\n download?: StringAttribute;\n src?: StringAttribute;\n alt?: StringAttribute;\n width?: Value<string | number | null>;\n height?: Value<string | number | null>;\n type?: StringAttribute;\n name?: StringAttribute;\n value?: ScalarAttribute;\n placeholder?: StringAttribute;\n for?: StringAttribute;\n charset?: StringAttribute;\n datetime?: StringAttribute;\n readonly?: BooleanAttribute;\n autofocus?: BooleanAttribute;\n required?: BooleanAttribute;\n disabled?: BooleanAttribute;\n checked?: BooleanAttribute;\n selected?: BooleanAttribute;\n multiple?: BooleanAttribute;\n open?: BooleanAttribute;\n controls?: BooleanAttribute;\n muted?: BooleanAttribute;\n loop?: BooleanAttribute;\n autoplay?: BooleanAttribute;\n novalidate?: BooleanAttribute;\n formnovalidate?: BooleanAttribute;\n maxlength?: Value<number | null>;\n minlength?: Value<number | null>;\n min?: StringAttribute;\n max?: StringAttribute;\n step?: StringAttribute;\n pattern?: StringAttribute;\n autocomplete?: StringAttribute;\n accept?: StringAttribute;\n \"accept-charset\"?: StringAttribute;\n \"http-equiv\"?: StringAttribute;\n content?: StringAttribute;\n media?: StringAttribute;\n method?: StringAttribute;\n action?: StringAttribute;\n enctype?: StringAttribute;\n rows?: Value<number | null>;\n cols?: Value<number | null>;\n colspan?: Value<number | null>;\n rowspan?: Value<number | null>;\n scope?: StringAttribute;\n cite?: StringAttribute;\n poster?: StringAttribute;\n loading?: StringAttribute;\n decoding?: StringAttribute;\n sizes?: StringAttribute;\n srcset?: StringAttribute;\n crossorigin?: StringAttribute;\n referrerpolicy?: StringAttribute;\n sandbox?: StringAttribute;\n allow?: StringAttribute;\n allowfullscreen?: BooleanAttribute;\n}\n\ntype HtmlProps<T extends Element = HTMLElement> = HtmlAttributes<T> & DataAria & EventProps;\ntype InputBase = Omit<HtmlProps<HTMLInputElement>, \"type\"> & {\n defaultValue?: string | undefined;\n defaultChecked?: boolean | undefined;\n};\ntype InputProps =\n | (InputBase & {\n type?: \"text\" | \"search\" | \"email\" | \"url\" | \"tel\" | \"password\" | undefined;\n modelValue?: Signal<string> | undefined;\n modelChecked?: never;\n })\n | (InputBase & {\n type: \"checkbox\";\n modelChecked?: Signal<boolean> | undefined;\n modelValue?: never;\n })\n | (InputBase & {\n type: \"radio\";\n name: string;\n value: string;\n modelValue?: Signal<string | null> | undefined;\n modelChecked?: never;\n })\n | (InputBase & {\n type: string;\n modelValue?: never;\n modelChecked?: never;\n });\ntype TextareaProps = HtmlProps<HTMLTextAreaElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\ntype SelectProps = HtmlProps<HTMLSelectElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\n\ninterface SvgAttributes extends CommonAttributes<SVGElement> {\n width?: DimensionAttribute;\n height?: DimensionAttribute;\n viewBox?: StringAttribute;\n preserveAspectRatio?: StringAttribute;\n gradientUnits?: StringAttribute;\n gradientTransform?: StringAttribute;\n markerWidth?: ScalarAttribute;\n markerHeight?: ScalarAttribute;\n refX?: ScalarAttribute;\n refY?: ScalarAttribute;\n \"xlink:href\"?: StringAttribute;\n \"xml:lang\"?: StringAttribute;\n \"stroke-width\"?: ScalarAttribute;\n \"fill-rule\"?: StringAttribute;\n \"clip-rule\"?: StringAttribute;\n \"stroke-linecap\"?: StringAttribute;\n \"stroke-linejoin\"?: StringAttribute;\n \"stop-color\"?: StringAttribute;\n \"stop-opacity\"?: ScalarAttribute;\n fill?: StringAttribute;\n stroke?: StringAttribute;\n d?: StringAttribute;\n x?: ScalarAttribute;\n y?: ScalarAttribute;\n x1?: ScalarAttribute;\n x2?: ScalarAttribute;\n y1?: ScalarAttribute;\n y2?: ScalarAttribute;\n cx?: ScalarAttribute;\n cy?: ScalarAttribute;\n r?: ScalarAttribute;\n rx?: ScalarAttribute;\n ry?: ScalarAttribute;\n points?: StringAttribute;\n transform?: StringAttribute;\n opacity?: ScalarAttribute;\n offset?: ScalarAttribute;\n id?: StringAttribute;\n}\n\ntype SvgProps = SvgAttributes & DataAria & EventProps;\ntype CustomProps = ReservedProps &\n EventProps & {\n [attribute: string]: StringAttribute | Child | Ref<Element> | Listener | undefined;\n };\n\ntype HtmlTag =\n | \"html\"\n | \"head\"\n | \"body\"\n | \"title\"\n | \"base\"\n | \"link\"\n | \"meta\"\n | \"style\"\n | \"script\"\n | \"div\"\n | \"span\"\n | \"p\"\n | \"a\"\n | \"br\"\n | \"hr\"\n | \"main\"\n | \"header\"\n | \"footer\"\n | \"nav\"\n | \"section\"\n | \"article\"\n | \"aside\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"ul\"\n | \"ol\"\n | \"li\"\n | \"dl\"\n | \"dt\"\n | \"dd\"\n | \"blockquote\"\n | \"pre\"\n | \"code\"\n | \"strong\"\n | \"em\"\n | \"b\"\n | \"i\"\n | \"small\"\n | \"mark\"\n | \"time\"\n | \"figure\"\n | \"figcaption\"\n | \"img\"\n | \"picture\"\n | \"source\"\n | \"video\"\n | \"audio\"\n | \"track\"\n | \"canvas\"\n | \"form\"\n | \"label\"\n | \"input\"\n | \"button\"\n | \"textarea\"\n | \"select\"\n | \"option\"\n | \"optgroup\"\n | \"fieldset\"\n | \"legend\"\n | \"output\"\n | \"progress\"\n | \"meter\"\n | \"datalist\"\n | \"table\"\n | \"caption\"\n | \"thead\"\n | \"tbody\"\n | \"tfoot\"\n | \"tr\"\n | \"th\"\n | \"td\"\n | \"col\"\n | \"colgroup\"\n | \"details\"\n | \"summary\"\n | \"dialog\"\n | \"template\"\n | \"slot\"\n | \"iframe\"\n | \"noscript\"\n | \"address\"\n | \"abbr\"\n | \"bdi\"\n | \"bdo\"\n | \"cite\"\n | \"data\"\n | \"del\"\n | \"dfn\"\n | \"ins\"\n | \"kbd\"\n | \"map\"\n | \"area\"\n | \"object\"\n | \"param\"\n | \"q\"\n | \"rp\"\n | \"rt\"\n | \"ruby\"\n | \"s\"\n | \"samp\"\n | \"sub\"\n | \"sup\"\n | \"u\"\n | \"var\"\n | \"wbr\"\n | \"embed\";\n\ntype SvgTag =\n | \"svg\"\n | \"g\"\n | \"path\"\n | \"circle\"\n | \"ellipse\"\n | \"rect\"\n | \"line\"\n | \"polyline\"\n | \"polygon\"\n | \"text\"\n | \"tspan\"\n | \"defs\"\n | \"symbol\"\n | \"use\"\n | \"clipPath\"\n | \"mask\"\n | \"linearGradient\"\n | \"radialGradient\"\n | \"stop\"\n | \"desc\"\n | \"foreignObject\";\n\nexport namespace JSX {\n export type Element = Child;\n export type ElementType =\n | string\n | Component<any>\n | typeof import(\"../island.js\").Island\n | typeof import(\"./description.js\").Fragment;\n export type IntrinsicElements = {\n [K in HtmlTag]: K extends \"input\"\n ? InputProps\n : K extends \"textarea\"\n ? TextareaProps\n : K extends \"select\"\n ? SelectProps\n : HtmlProps;\n } & { [K in SvgTag]: SvgProps } & {\n [K in `${string}-${string}`]: CustomProps;\n };\n export interface IntrinsicAttributes {\n key?: Key | undefined;\n }\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n}\n"]}
1
+ {"version":3,"file":"jsx-types.js","sourceRoot":"","sources":["../../src/zudo-react/jsx-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CSSProperties } from \"./style.js\";\nexport type { CSSProperties, CssProperty } from \"./style.js\";\nimport type { Child, Component, Description, Key } from \"./description.js\";\nimport type { Listener, Ref } from \"./index.js\";\nimport type { ReadonlySignal, Signal } from \"./reactive-types.js\";\n\ntype Value<T> = T | ReadonlySignal<T> | undefined;\ntype ScalarAttribute = Value<string | number | boolean | null>;\ntype DimensionAttribute = Value<string | number | null>;\ntype StringAttribute = Value<string | null>;\ntype BooleanAttribute = Value<boolean | null>;\n// The custom-name index must also accept every mapped listener under strict function variance.\ntype AnyListener = Listener<any>;\ntype EventProps<TEl extends Element, TMap extends Record<keyof TMap, Event>> = {\n [K in keyof TMap & string as `on:${K}` | `on:${K}:capture`]?: Listener<\n TMap[K] & { currentTarget: TEl }\n >;\n} & {\n [name: `on:${string}`]: AnyListener | undefined;\n};\ntype DataAria = {\n [name: `data-${string}`]: ScalarAttribute;\n} & {\n [name: `aria-${string}`]: ScalarAttribute;\n};\n\ninterface ReservedProps<T extends Element = Element> {\n children?: Child | undefined;\n key?: Key | undefined;\n ref?: Ref<T> | undefined;\n rawHtml?: Value<string | null>;\n}\n\ninterface CommonAttributes<T extends Element = Element> extends ReservedProps<T> {\n id?: StringAttribute;\n class?: StringAttribute;\n title?: StringAttribute;\n lang?: StringAttribute;\n dir?: StringAttribute;\n slot?: StringAttribute;\n role?: StringAttribute;\n style?: Value<string | CSSProperties | null>;\n hidden?: BooleanAttribute;\n inert?: BooleanAttribute;\n contenteditable?: Value<string | boolean | null>;\n draggable?: Value<string | boolean | null>;\n spellcheck?: Value<string | boolean | null>;\n tabindex?: Value<number | null>;\n accesskey?: StringAttribute;\n translate?: StringAttribute;\n onclick?: string | undefined;\n onload?: string | undefined;\n onerror?: string | undefined;\n}\n\ninterface HtmlBaseAttributes<T extends HTMLElement = HTMLElement> extends CommonAttributes<T> {\n href?: StringAttribute;\n target?: StringAttribute;\n rel?: StringAttribute;\n download?: Value<string | boolean | null>;\n property?: StringAttribute;\n itemprop?: StringAttribute;\n hreflang?: StringAttribute;\n as?: StringAttribute;\n integrity?: StringAttribute;\n async?: BooleanAttribute;\n defer?: BooleanAttribute;\n nonce?: StringAttribute;\n popover?: StringAttribute;\n popovertarget?: StringAttribute;\n popovertargetaction?: StringAttribute;\n srcdoc?: StringAttribute;\n fetchpriority?: StringAttribute;\n inputmode?: StringAttribute;\n autocapitalize?: StringAttribute;\n form?: StringAttribute;\n label?: StringAttribute;\n preload?: StringAttribute;\n playsinline?: BooleanAttribute;\n wrap?: StringAttribute;\n closedby?: StringAttribute;\n src?: StringAttribute;\n alt?: StringAttribute;\n width?: Value<string | number | null>;\n height?: Value<string | number | null>;\n type?: StringAttribute;\n name?: StringAttribute;\n value?: string | number | null | undefined;\n placeholder?: StringAttribute;\n for?: StringAttribute;\n charset?: StringAttribute;\n datetime?: StringAttribute;\n readonly?: BooleanAttribute;\n autofocus?: BooleanAttribute;\n required?: BooleanAttribute;\n disabled?: BooleanAttribute;\n checked?: boolean | null | undefined;\n selected?: BooleanAttribute;\n multiple?: BooleanAttribute;\n reversed?: BooleanAttribute;\n open?: BooleanAttribute;\n controls?: BooleanAttribute;\n muted?: BooleanAttribute;\n loop?: BooleanAttribute;\n autoplay?: BooleanAttribute;\n novalidate?: BooleanAttribute;\n formnovalidate?: BooleanAttribute;\n maxlength?: Value<number | null>;\n minlength?: Value<number | null>;\n min?: StringAttribute;\n max?: StringAttribute;\n step?: StringAttribute;\n start?: Value<string | number | null>;\n pattern?: StringAttribute;\n autocomplete?: StringAttribute;\n accept?: StringAttribute;\n \"accept-charset\"?: StringAttribute;\n \"http-equiv\"?: StringAttribute;\n content?: StringAttribute;\n media?: StringAttribute;\n method?: StringAttribute;\n action?: StringAttribute;\n enctype?: StringAttribute;\n rows?: Value<number | null>;\n cols?: Value<number | null>;\n colspan?: Value<number | null>;\n rowspan?: Value<number | null>;\n scope?: StringAttribute;\n cite?: StringAttribute;\n poster?: StringAttribute;\n loading?: StringAttribute;\n decoding?: StringAttribute;\n sizes?: StringAttribute;\n srcset?: StringAttribute;\n crossorigin?: StringAttribute;\n referrerpolicy?: StringAttribute;\n sandbox?: StringAttribute;\n allow?: StringAttribute;\n allowfullscreen?: BooleanAttribute;\n}\n\nexport type HTMLAttributes<T extends HTMLElement = HTMLElement> = HtmlBaseAttributes<T> &\n DataAria &\n EventProps<T, HTMLElementEventMap>;\ntype RawTextProps<T extends HTMLElement = HTMLElement> = Omit<\n HtmlBaseAttributes<T>,\n \"children\" | \"rawHtml\"\n> &\n DataAria &\n EventProps<T, HTMLElementEventMap> & {\n children?: never;\n rawHtml?: string | undefined;\n };\ntype IframeProps = Omit<HtmlBaseAttributes<HTMLIFrameElement>, \"children\" | \"rawHtml\"> &\n DataAria &\n EventProps<HTMLIFrameElement, HTMLElementEventMap> & {\n children?: never;\n rawHtml?: never;\n };\ntype InputBase = Omit<HtmlBaseAttributes<HTMLInputElement>, \"type\"> &\n DataAria &\n EventProps<HTMLInputElement, HTMLElementEventMap> & {\n defaultValue?: string | undefined;\n defaultChecked?: boolean | undefined;\n };\nexport type InputProps = InputBase &\n (\n | {\n type?: \"text\" | \"search\" | \"email\" | \"url\" | \"tel\" | \"password\" | undefined;\n modelValue?: Signal<string> | undefined;\n modelChecked?: never;\n }\n | {\n type: \"checkbox\";\n modelChecked?: Signal<boolean> | undefined;\n modelValue?: never;\n }\n | {\n type: \"radio\";\n name: string;\n value: string;\n modelValue?: Signal<string | null> | undefined;\n modelChecked?: never;\n }\n | {\n type: string;\n modelValue?: never;\n modelChecked?: never;\n }\n );\nexport type TextareaProps = HTMLAttributes<HTMLTextAreaElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\nexport type SelectProps = HTMLAttributes<HTMLSelectElement> & {\n modelValue?: Signal<string> | undefined;\n defaultValue?: string | undefined;\n};\n\ninterface SvgBaseAttributes<T extends SVGElement = SVGElement> extends CommonAttributes<T> {\n width?: DimensionAttribute;\n height?: DimensionAttribute;\n viewBox?: StringAttribute;\n preserveAspectRatio?: StringAttribute;\n gradientUnits?: StringAttribute;\n gradientTransform?: StringAttribute;\n markerWidth?: ScalarAttribute;\n markerHeight?: ScalarAttribute;\n refX?: ScalarAttribute;\n refY?: ScalarAttribute;\n \"xlink:href\"?: StringAttribute;\n \"xml:lang\"?: StringAttribute;\n xmlns?: StringAttribute;\n \"xmlns:xlink\"?: StringAttribute;\n href?: StringAttribute;\n focusable?: StringAttribute;\n \"stroke-width\"?: ScalarAttribute;\n \"fill-rule\"?: StringAttribute;\n \"clip-rule\"?: StringAttribute;\n \"stroke-linecap\"?: StringAttribute;\n \"stroke-linejoin\"?: StringAttribute;\n \"stop-color\"?: StringAttribute;\n \"stop-opacity\"?: ScalarAttribute;\n \"fill-opacity\"?: ScalarAttribute;\n \"stroke-dasharray\"?: StringAttribute;\n \"text-anchor\"?: StringAttribute;\n fill?: StringAttribute;\n stroke?: StringAttribute;\n d?: StringAttribute;\n x?: ScalarAttribute;\n y?: ScalarAttribute;\n x1?: ScalarAttribute;\n x2?: ScalarAttribute;\n y1?: ScalarAttribute;\n y2?: ScalarAttribute;\n cx?: ScalarAttribute;\n cy?: ScalarAttribute;\n r?: ScalarAttribute;\n rx?: ScalarAttribute;\n ry?: ScalarAttribute;\n points?: StringAttribute;\n transform?: StringAttribute;\n opacity?: ScalarAttribute;\n offset?: ScalarAttribute;\n id?: StringAttribute;\n}\n\nexport type SVGAttributes<T extends SVGElement = SVGElement> = SvgBaseAttributes<T> &\n DataAria &\n EventProps<T, SVGElementEventMap>;\ntype CustomProps = ReservedProps &\n EventProps<HTMLElement, GlobalEventHandlersEventMap> & {\n value?: string | null | undefined;\n checked?: null | undefined;\n [attribute: string]: StringAttribute | Child | Ref<Element> | AnyListener | undefined;\n };\n\ntype HtmlTag =\n | \"html\"\n | \"head\"\n | \"body\"\n | \"title\"\n | \"base\"\n | \"link\"\n | \"meta\"\n | \"style\"\n | \"script\"\n | \"div\"\n | \"span\"\n | \"p\"\n | \"a\"\n | \"br\"\n | \"hr\"\n | \"main\"\n | \"header\"\n | \"footer\"\n | \"nav\"\n | \"section\"\n | \"article\"\n | \"aside\"\n | \"search\"\n | \"hgroup\"\n | \"menu\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"ul\"\n | \"ol\"\n | \"li\"\n | \"dl\"\n | \"dt\"\n | \"dd\"\n | \"blockquote\"\n | \"pre\"\n | \"code\"\n | \"strong\"\n | \"em\"\n | \"b\"\n | \"i\"\n | \"small\"\n | \"mark\"\n | \"time\"\n | \"figure\"\n | \"figcaption\"\n | \"img\"\n | \"picture\"\n | \"source\"\n | \"video\"\n | \"audio\"\n | \"track\"\n | \"canvas\"\n | \"form\"\n | \"label\"\n | \"input\"\n | \"button\"\n | \"textarea\"\n | \"select\"\n | \"option\"\n | \"optgroup\"\n | \"fieldset\"\n | \"legend\"\n | \"output\"\n | \"progress\"\n | \"meter\"\n | \"datalist\"\n | \"table\"\n | \"caption\"\n | \"thead\"\n | \"tbody\"\n | \"tfoot\"\n | \"tr\"\n | \"th\"\n | \"td\"\n | \"col\"\n | \"colgroup\"\n | \"details\"\n | \"summary\"\n | \"dialog\"\n | \"template\"\n | \"slot\"\n | \"iframe\"\n | \"noscript\"\n | \"address\"\n | \"abbr\"\n | \"bdi\"\n | \"bdo\"\n | \"cite\"\n | \"data\"\n | \"del\"\n | \"dfn\"\n | \"ins\"\n | \"kbd\"\n | \"map\"\n | \"area\"\n | \"object\"\n | \"param\"\n | \"q\"\n | \"rp\"\n | \"rt\"\n | \"ruby\"\n | \"s\"\n | \"samp\"\n | \"sub\"\n | \"sup\"\n | \"u\"\n | \"var\"\n | \"wbr\"\n | \"embed\";\n\ntype SvgTag =\n | \"svg\"\n | \"g\"\n | \"path\"\n | \"circle\"\n | \"ellipse\"\n | \"rect\"\n | \"line\"\n | \"polyline\"\n | \"polygon\"\n | \"text\"\n | \"tspan\"\n | \"defs\"\n | \"symbol\"\n | \"use\"\n | \"clipPath\"\n | \"mask\"\n | \"linearGradient\"\n | \"radialGradient\"\n | \"stop\"\n | \"desc\"\n | \"foreignObject\"\n | \"pattern\"\n | \"filter\"\n | \"marker\"\n | \"image\";\n\n/** DOM element corresponding to an owned intrinsic tag. */\nexport type ElementForTag<Tag extends HtmlTag | SvgTag> = Tag extends HtmlTag\n ? Tag extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[Tag]\n : HTMLElement\n : Tag extends keyof SVGElementTagNameMap\n ? SVGElementTagNameMap[Tag]\n : SVGElement;\n\nexport namespace JSX {\n export type Element = Description;\n export type HTMLAttributes<T extends HTMLElement = HTMLElement> =\n import(\"./jsx-types.js\").HTMLAttributes<T>;\n export type SVGAttributes<T extends SVGElement = SVGElement> =\n import(\"./jsx-types.js\").SVGAttributes<T>;\n export type CSSProperties = import(\"./jsx-types.js\").CSSProperties;\n export type ElementType =\n | string\n | Component<any>\n | typeof import(\"../island.js\").Island\n | typeof import(\"./description.js\").Fragment;\n export type IntrinsicElements = {\n [K in HtmlTag]: K extends \"input\"\n ? InputProps\n : K extends \"textarea\"\n ? TextareaProps\n : K extends \"select\"\n ? SelectProps\n : K extends \"iframe\"\n ? IframeProps\n : K extends \"script\" | \"style\"\n ? RawTextProps<ElementForTag<K>>\n : HTMLAttributes<ElementForTag<K>>;\n } & {\n [K in SvgTag]: SVGAttributes<ElementForTag<K>>;\n } & {\n [K in `${string}-${string}`]: CustomProps;\n };\n export interface IntrinsicAttributes {\n key?: Key | undefined;\n }\n export interface ElementChildrenAttribute {\n children: unknown;\n }\n}\n"]}
@@ -1,2 +1,4 @@
1
+ export declare function normalizeProps(props: Record<string, unknown>): Record<string, unknown>;
1
2
  export declare function serializeProps(props: Record<string, unknown>): string;
3
+ export declare function emptyChildren(value: unknown, ancestors?: Set<object>): boolean;
2
4
  export declare function parseProps(json: string): Record<string, unknown>;
@@ -2,13 +2,13 @@ const forbidden = new Set(["__proto__", "prototype", "constructor"]);
2
2
  function fail(code, path, detail = "") {
3
3
  throw new TypeError(`${code} at ${path}${detail ? ` (${detail})` : ""}`);
4
4
  }
5
- function validate(value, path, ancestors) {
5
+ function normalize(value, path, ancestors) {
6
6
  if (value === null || typeof value === "string" || typeof value === "boolean")
7
- return;
7
+ return value;
8
8
  if (typeof value === "number") {
9
9
  if (!Number.isFinite(value))
10
10
  fail("ZR_PROPS_NUMBER", path);
11
- return;
11
+ return value;
12
12
  }
13
13
  if (value === undefined)
14
14
  fail("ZR_PROPS_UNDEFINED", path);
@@ -23,6 +23,7 @@ function validate(value, path, ancestors) {
23
23
  if (ancestor !== undefined)
24
24
  fail("ZR_PROPS_CYCLE", path, `ancestor ${ancestor}`);
25
25
  const array = Array.isArray(record);
26
+ const length = array ? record.length : 0;
26
27
  if (!array &&
27
28
  Object.getPrototypeOf(record) !== Object.prototype &&
28
29
  Object.getPrototypeOf(record) !== null)
@@ -30,6 +31,9 @@ function validate(value, path, ancestors) {
30
31
  ancestors.set(record, path);
31
32
  try {
32
33
  const descriptors = Object.getOwnPropertyDescriptors(record);
34
+ const copy = array
35
+ ? []
36
+ : Object.create(Object.getPrototypeOf(record));
33
37
  for (const key of Reflect.ownKeys(descriptors)) {
34
38
  if (typeof key === "symbol")
35
39
  fail("ZR_PROPS_PROPERTY", path, "symbol key");
@@ -41,22 +45,30 @@ function validate(value, path, ancestors) {
41
45
  const descriptor = descriptors[key];
42
46
  if (!descriptor || !descriptor.enumerable || !("value" in descriptor))
43
47
  fail("ZR_PROPS_PROPERTY", next);
44
- if (array && (!/^(0|[1-9]\d*)$/.test(key) || Number(key) >= record.length))
48
+ if (array && (!/^(0|[1-9]\d*)$/.test(key) || Number(key) >= length))
45
49
  fail("ZR_PROPS_PROPERTY", next);
46
- validate(descriptor.value, next, ancestors);
50
+ if (!array && descriptor.value === undefined)
51
+ continue;
52
+ Object.defineProperty(copy, key, {
53
+ value: normalize(descriptor.value, next, ancestors),
54
+ enumerable: true,
55
+ writable: true,
56
+ configurable: true,
57
+ });
47
58
  }
48
59
  if (array) {
49
- for (let index = 0; index < record.length; index++) {
60
+ for (let index = 0; index < length; index++) {
50
61
  if (!Object.hasOwn(record, index))
51
62
  fail("ZR_PROPS_UNDEFINED", `${path}[${index}]`);
52
63
  }
53
64
  }
65
+ return copy;
54
66
  }
55
67
  finally {
56
68
  ancestors.delete(record);
57
69
  }
58
70
  }
59
- export function serializeProps(props) {
71
+ export function normalizeProps(props) {
60
72
  if (props === null || Array.isArray(props) || typeof props !== "object")
61
73
  fail("ZR_PROPS_OBJECT_KIND", "props");
62
74
  const descriptors = Object.getOwnPropertyDescriptors(props);
@@ -69,13 +81,29 @@ export function serializeProps(props) {
69
81
  delete descriptors.children;
70
82
  }
71
83
  const payload = Object.defineProperties(Object.create(Object.getPrototypeOf(props)), descriptors);
72
- validate(payload, "props", new Map());
73
- return JSON.stringify(payload);
84
+ return normalize(payload, "props", new Map());
74
85
  }
75
- function emptyChildren(value) {
76
- return (value == null ||
77
- typeof value === "boolean" ||
78
- (Array.isArray(value) && value.every(emptyChildren)));
86
+ export function serializeProps(props) {
87
+ return JSON.stringify(normalizeProps(props));
88
+ }
89
+ export function emptyChildren(value, ancestors = new Set()) {
90
+ if (value == null || typeof value === "boolean")
91
+ return true;
92
+ if (!Array.isArray(value) || ancestors.has(value))
93
+ return false;
94
+ ancestors.add(value);
95
+ try {
96
+ const descriptors = Object.getOwnPropertyDescriptors(value);
97
+ for (let index = 0; index < value.length; index++) {
98
+ const descriptor = descriptors[index];
99
+ if (descriptor && (!("value" in descriptor) || !emptyChildren(descriptor.value, ancestors)))
100
+ return false;
101
+ }
102
+ return true;
103
+ }
104
+ finally {
105
+ ancestors.delete(value);
106
+ }
79
107
  }
80
108
  export function parseProps(json) {
81
109
  let parsed;
@@ -89,7 +117,7 @@ export function parseProps(json) {
89
117
  fail("ZR_PROPS_OBJECT_KIND", "props");
90
118
  if (Object.hasOwn(parsed, "children"))
91
119
  fail("ZR_PROPS_CHILDREN", "props.children");
92
- validate(parsed, "props", new Map());
120
+ normalize(parsed, "props", new Map());
93
121
  return parsed;
94
122
  }
95
123
  //# sourceMappingURL=props-transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"props-transport.js","sourceRoot":"","sources":["../../src/zudo-react/props-transport.ts"],"names":[],"mappings":"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","sourcesContent":["const forbidden = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\nfunction fail(code: string, path: string, detail = \"\"): never {\n throw new TypeError(`${code} at ${path}${detail ? ` (${detail})` : \"\"}`);\n}\n\nfunction validate(value: unknown, path: string, ancestors: Map<object, string>): void {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return;\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) fail(\"ZR_PROPS_NUMBER\", path);\n return;\n }\n if (value === undefined) fail(\"ZR_PROPS_UNDEFINED\", path);\n if (typeof value === \"function\" || typeof value === \"symbol\" || typeof value === \"bigint\")\n fail(`ZR_PROPS_${typeof value}`.toUpperCase(), path);\n if (typeof value !== \"object\") fail(\"ZR_PROPS_VALUE\", path);\n const record = value as object;\n if (\"$$zudo\" in record || \"$$zudoReactive\" in record) fail(\"ZR_PROPS_RUNTIME_VALUE\", path);\n const ancestor = ancestors.get(record);\n if (ancestor !== undefined) fail(\"ZR_PROPS_CYCLE\", path, `ancestor ${ancestor}`);\n const array = Array.isArray(record);\n if (\n !array &&\n Object.getPrototypeOf(record) !== Object.prototype &&\n Object.getPrototypeOf(record) !== null\n )\n fail(\"ZR_PROPS_OBJECT_KIND\", path);\n ancestors.set(record, path);\n try {\n const descriptors = Object.getOwnPropertyDescriptors(record);\n for (const key of Reflect.ownKeys(descriptors)) {\n if (typeof key === \"symbol\") fail(\"ZR_PROPS_PROPERTY\", path, \"symbol key\");\n if (array && key === \"length\") continue;\n const next = array ? `${path}[${key}]` : `${path}.${key}`;\n if (forbidden.has(key)) fail(\"ZR_PROPS_KEY\", next);\n const descriptor = descriptors[key];\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor))\n fail(\"ZR_PROPS_PROPERTY\", next);\n if (array && (!/^(0|[1-9]\\d*)$/.test(key) || Number(key) >= record.length))\n fail(\"ZR_PROPS_PROPERTY\", next);\n validate(descriptor.value, next, ancestors);\n }\n if (array) {\n for (let index = 0; index < record.length; index++) {\n if (!Object.hasOwn(record, index)) fail(\"ZR_PROPS_UNDEFINED\", `${path}[${index}]`);\n }\n }\n } finally {\n ancestors.delete(record);\n }\n}\n\nexport function serializeProps(props: Record<string, unknown>): string {\n if (props === null || Array.isArray(props) || typeof props !== \"object\")\n fail(\"ZR_PROPS_OBJECT_KIND\", \"props\");\n const descriptors = Object.getOwnPropertyDescriptors(props);\n const child = descriptors.children;\n if (child) {\n if (!child.enumerable || !(\"value\" in child)) fail(\"ZR_PROPS_PROPERTY\", \"props.children\");\n if (!emptyChildren(child.value)) fail(\"ZR_PROPS_CHILDREN\", \"props.children\");\n delete descriptors.children;\n }\n const payload = Object.defineProperties(Object.create(Object.getPrototypeOf(props)), descriptors);\n validate(payload, \"props\", new Map());\n return JSON.stringify(payload);\n}\n\nfunction emptyChildren(value: unknown): boolean {\n return (\n value == null ||\n typeof value === \"boolean\" ||\n (Array.isArray(value) && value.every(emptyChildren))\n );\n}\n\nexport function parseProps(json: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n fail(\"ZR_PROPS_JSON\", \"props\");\n }\n if (parsed === null || Array.isArray(parsed) || typeof parsed !== \"object\")\n fail(\"ZR_PROPS_OBJECT_KIND\", \"props\");\n if (Object.hasOwn(parsed, \"children\")) fail(\"ZR_PROPS_CHILDREN\", \"props.children\");\n validate(parsed, \"props\", new Map());\n return parsed as Record<string, unknown>;\n}\n"]}
1
+ {"version":3,"file":"props-transport.js","sourceRoot":"","sources":["../../src/zudo-react/props-transport.ts"],"names":[],"mappings":"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","sourcesContent":["const forbidden = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\nfunction fail(code: string, path: string, detail = \"\"): never {\n throw new TypeError(`${code} at ${path}${detail ? ` (${detail})` : \"\"}`);\n}\n\nfunction normalize(value: unknown, path: string, ancestors: Map<object, string>): unknown {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) fail(\"ZR_PROPS_NUMBER\", path);\n return value;\n }\n if (value === undefined) fail(\"ZR_PROPS_UNDEFINED\", path);\n if (typeof value === \"function\" || typeof value === \"symbol\" || typeof value === \"bigint\")\n fail(`ZR_PROPS_${typeof value}`.toUpperCase(), path);\n if (typeof value !== \"object\") fail(\"ZR_PROPS_VALUE\", path);\n const record = value as object;\n if (\"$$zudo\" in record || \"$$zudoReactive\" in record) fail(\"ZR_PROPS_RUNTIME_VALUE\", path);\n const ancestor = ancestors.get(record);\n if (ancestor !== undefined) fail(\"ZR_PROPS_CYCLE\", path, `ancestor ${ancestor}`);\n const array = Array.isArray(record);\n const length = array ? (record as unknown[]).length : 0;\n if (\n !array &&\n Object.getPrototypeOf(record) !== Object.prototype &&\n Object.getPrototypeOf(record) !== null\n )\n fail(\"ZR_PROPS_OBJECT_KIND\", path);\n ancestors.set(record, path);\n try {\n const descriptors = Object.getOwnPropertyDescriptors(record);\n const copy: Record<string, unknown> | unknown[] = array\n ? []\n : Object.create(Object.getPrototypeOf(record));\n for (const key of Reflect.ownKeys(descriptors)) {\n if (typeof key === \"symbol\") fail(\"ZR_PROPS_PROPERTY\", path, \"symbol key\");\n if (array && key === \"length\") continue;\n const next = array ? `${path}[${key}]` : `${path}.${key}`;\n if (forbidden.has(key)) fail(\"ZR_PROPS_KEY\", next);\n const descriptor = descriptors[key];\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor))\n fail(\"ZR_PROPS_PROPERTY\", next);\n if (array && (!/^(0|[1-9]\\d*)$/.test(key) || Number(key) >= length))\n fail(\"ZR_PROPS_PROPERTY\", next);\n if (!array && descriptor.value === undefined) continue;\n Object.defineProperty(copy, key, {\n value: normalize(descriptor.value, next, ancestors),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n if (array) {\n for (let index = 0; index < length; index++) {\n if (!Object.hasOwn(record, index)) fail(\"ZR_PROPS_UNDEFINED\", `${path}[${index}]`);\n }\n }\n return copy;\n } finally {\n ancestors.delete(record);\n }\n}\n\nexport function normalizeProps(props: Record<string, unknown>): Record<string, unknown> {\n if (props === null || Array.isArray(props) || typeof props !== \"object\")\n fail(\"ZR_PROPS_OBJECT_KIND\", \"props\");\n const descriptors = Object.getOwnPropertyDescriptors(props);\n const child = descriptors.children;\n if (child) {\n if (!child.enumerable || !(\"value\" in child)) fail(\"ZR_PROPS_PROPERTY\", \"props.children\");\n if (!emptyChildren(child.value)) fail(\"ZR_PROPS_CHILDREN\", \"props.children\");\n delete descriptors.children;\n }\n const payload = Object.defineProperties(Object.create(Object.getPrototypeOf(props)), descriptors);\n return normalize(payload, \"props\", new Map()) as Record<string, unknown>;\n}\n\nexport function serializeProps(props: Record<string, unknown>): string {\n return JSON.stringify(normalizeProps(props));\n}\n\nexport function emptyChildren(value: unknown, ancestors = new Set<object>()): boolean {\n if (value == null || typeof value === \"boolean\") return true;\n if (!Array.isArray(value) || ancestors.has(value)) return false;\n ancestors.add(value);\n try {\n const descriptors = Object.getOwnPropertyDescriptors(value);\n for (let index = 0; index < value.length; index++) {\n const descriptor = descriptors[index];\n if (descriptor && (!(\"value\" in descriptor) || !emptyChildren(descriptor.value, ancestors)))\n return false;\n }\n return true;\n } finally {\n ancestors.delete(value);\n }\n}\n\nexport function parseProps(json: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n fail(\"ZR_PROPS_JSON\", \"props\");\n }\n if (parsed === null || Array.isArray(parsed) || typeof parsed !== \"object\")\n fail(\"ZR_PROPS_OBJECT_KIND\", \"props\");\n if (Object.hasOwn(parsed, \"children\")) fail(\"ZR_PROPS_CHILDREN\", \"props.children\");\n normalize(parsed, \"props\", new Map());\n return parsed as Record<string, unknown>;\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function rawHtmlReserved(payload: string, tag: string): boolean;
@@ -0,0 +1,120 @@
1
+ // Reserved-boundary guard for rawHtml payloads, shared by the server renderer
2
+ // and the client runtime so both accept exactly the same payloads.
3
+ //
4
+ // Rule: a payload is rejected when it can create a reserved boundary, decided
5
+ // by an HTML-tokenizer pass (WHATWG tokenization, data state), not a text regex:
6
+ // - a start or end tag carrying an attribute whose ASCII-lowercased name is
7
+ // `data-zfb-island` or `data-zfb-island-skip-ssr` (any value form, or none);
8
+ // - a comment, including a bogus `<!…>`, `<?…>` or `</…>` comment, whose data
9
+ // contains `zr:1:` (hydration matches `zr:1:` / `/zr:1:` comment prefixes);
10
+ // - a payload that ends inside a tag, comment or `</`, which would absorb the
11
+ // renderer's closing boundary marker.
12
+ // Marker-like text in character data or quoted attribute values is inert and
13
+ // renders as written. The tokenizer models the data state only, so payloads it
14
+ // cannot model take the textual rule, which rejects any `data-zfb-island` or
15
+ // `zr:1:` occurrence: `noscript`/`xmp`/`noembed`/`noframes`/`plaintext` hosts,
16
+ // and payloads naming a RAWTEXT/RCDATA/script/PLAINTEXT element (its end tag may
17
+ // also close a raw-text ancestor) or a CDATA section (foreign content).
18
+ // `script`/`style` hosts are raw text: their payload cannot form markup, and
19
+ // they keep the documented contract (no protocol comment or island attribute
20
+ // text; the callers reject `</script` / `</style`).
21
+ const reservedAttributes = new Set(["data-zfb-island", "data-zfb-island-skip-ssr"]);
22
+ const rawTextHosts = new Set(["noscript", "xmp", "noembed", "noframes", "plaintext"]);
23
+ const unmodeled = /<\/?(?:script|style|textarea|title|xmp|iframe|noembed|noframes|noscript|plaintext)|<!\[cdata\[/i;
24
+ const space = /[\t\n\f\r ]/;
25
+ const nameEnd = /[\t\n\f\r />=]/;
26
+ const unquotedEnd = /[\t\n\f\r >]/;
27
+ export function rawHtmlReserved(payload, tag) {
28
+ if (tag === "script" || tag === "style")
29
+ return /<!--\/?zr:1:|data-zfb-island(?:-skip-ssr)?\s*=/.test(payload);
30
+ if (rawTextHosts.has(tag) || unmodeled.test(payload))
31
+ return /data-zfb-island|zr:1:/i.test(payload);
32
+ let i = 0;
33
+ for (;;) {
34
+ const lt = payload.indexOf("<", i);
35
+ if (lt < 0)
36
+ return false;
37
+ const c = payload[lt + 1];
38
+ let start;
39
+ if (c === undefined)
40
+ return false;
41
+ if (/[a-z]/i.test(c) || (c === "/" && /[a-z]/i.test(payload[lt + 2] ?? ""))) {
42
+ i = tagEnd(payload, c === "/" ? lt + 2 : lt + 1);
43
+ if (i < 0)
44
+ return true;
45
+ continue;
46
+ }
47
+ if (c === "!" && payload.startsWith("--", lt + 2)) {
48
+ start = lt + 4;
49
+ if (payload[start] === ">" || payload.startsWith("->", start)) {
50
+ i = start;
51
+ continue;
52
+ }
53
+ const dashes = payload.indexOf("-->", start);
54
+ const bang = payload.indexOf("--!>", start);
55
+ const end = dashes < 0 || (bang >= 0 && bang < dashes) ? bang : dashes;
56
+ if (end < 0 || payload.slice(start, end).includes("zr:1:"))
57
+ return true;
58
+ i = end;
59
+ continue;
60
+ }
61
+ if (c === "/") {
62
+ // `</` followed by the closing marker's `<` would open a bogus comment.
63
+ if (lt + 2 >= payload.length)
64
+ return true;
65
+ if (payload[lt + 2] === ">") {
66
+ i = lt + 3;
67
+ continue;
68
+ }
69
+ start = lt + 2;
70
+ }
71
+ else if (c === "!" || c === "?")
72
+ start = lt + 1;
73
+ else {
74
+ i = lt + 1;
75
+ continue;
76
+ }
77
+ const end = payload.indexOf(">", start);
78
+ if (end < 0 || payload.slice(start, end).includes("zr:1:"))
79
+ return true;
80
+ i = end;
81
+ }
82
+ }
83
+ // Returns the index just past the tag's `>`, or -1 when the tag is unterminated
84
+ // or carries a reserved attribute.
85
+ function tagEnd(s, j) {
86
+ const n = s.length;
87
+ while (j < n && !space.test(s[j]) && s[j] !== "/" && s[j] !== ">")
88
+ j++;
89
+ for (;;) {
90
+ while (j < n && (space.test(s[j]) || s[j] === "/"))
91
+ j++;
92
+ if (j >= n)
93
+ return -1;
94
+ if (s[j] === ">")
95
+ return j + 1;
96
+ const start = j++;
97
+ while (j < n && !nameEnd.test(s[j]))
98
+ j++;
99
+ if (reservedAttributes.has(s.slice(start, j).toLowerCase()))
100
+ return -1;
101
+ while (j < n && space.test(s[j]))
102
+ j++;
103
+ if (s[j] !== "=")
104
+ continue;
105
+ j++;
106
+ while (j < n && space.test(s[j]))
107
+ j++;
108
+ const quote = s[j];
109
+ if (quote === '"' || quote === "'") {
110
+ const close = s.indexOf(quote, j + 1);
111
+ if (close < 0)
112
+ return -1;
113
+ j = close + 1;
114
+ }
115
+ else
116
+ while (j < n && !unquotedEnd.test(s[j]))
117
+ j++;
118
+ }
119
+ }
120
+ //# sourceMappingURL=raw-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-html.js","sourceRoot":"","sources":["../../src/zudo-react/raw-html.ts"],"names":[],"mappings":"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","sourcesContent":["// Reserved-boundary guard for rawHtml payloads, shared by the server renderer\n// and the client runtime so both accept exactly the same payloads.\n//\n// Rule: a payload is rejected when it can create a reserved boundary, decided\n// by an HTML-tokenizer pass (WHATWG tokenization, data state), not a text regex:\n// - a start or end tag carrying an attribute whose ASCII-lowercased name is\n// `data-zfb-island` or `data-zfb-island-skip-ssr` (any value form, or none);\n// - a comment, including a bogus `<!…>`, `<?…>` or `</…>` comment, whose data\n// contains `zr:1:` (hydration matches `zr:1:` / `/zr:1:` comment prefixes);\n// - a payload that ends inside a tag, comment or `</`, which would absorb the\n// renderer's closing boundary marker.\n// Marker-like text in character data or quoted attribute values is inert and\n// renders as written. The tokenizer models the data state only, so payloads it\n// cannot model take the textual rule, which rejects any `data-zfb-island` or\n// `zr:1:` occurrence: `noscript`/`xmp`/`noembed`/`noframes`/`plaintext` hosts,\n// and payloads naming a RAWTEXT/RCDATA/script/PLAINTEXT element (its end tag may\n// also close a raw-text ancestor) or a CDATA section (foreign content).\n// `script`/`style` hosts are raw text: their payload cannot form markup, and\n// they keep the documented contract (no protocol comment or island attribute\n// text; the callers reject `</script` / `</style`).\n\nconst reservedAttributes = new Set([\"data-zfb-island\", \"data-zfb-island-skip-ssr\"]);\nconst rawTextHosts = new Set([\"noscript\", \"xmp\", \"noembed\", \"noframes\", \"plaintext\"]);\nconst unmodeled =\n /<\\/?(?:script|style|textarea|title|xmp|iframe|noembed|noframes|noscript|plaintext)|<!\\[cdata\\[/i;\nconst space = /[\\t\\n\\f\\r ]/;\nconst nameEnd = /[\\t\\n\\f\\r />=]/;\nconst unquotedEnd = /[\\t\\n\\f\\r >]/;\n\nexport function rawHtmlReserved(payload: string, tag: string): boolean {\n if (tag === \"script\" || tag === \"style\")\n return /<!--\\/?zr:1:|data-zfb-island(?:-skip-ssr)?\\s*=/.test(payload);\n if (rawTextHosts.has(tag) || unmodeled.test(payload))\n return /data-zfb-island|zr:1:/i.test(payload);\n let i = 0;\n for (;;) {\n const lt = payload.indexOf(\"<\", i);\n if (lt < 0) return false;\n const c = payload[lt + 1];\n let start: number;\n if (c === undefined) return false;\n if (/[a-z]/i.test(c) || (c === \"/\" && /[a-z]/i.test(payload[lt + 2] ?? \"\"))) {\n i = tagEnd(payload, c === \"/\" ? lt + 2 : lt + 1);\n if (i < 0) return true;\n continue;\n }\n if (c === \"!\" && payload.startsWith(\"--\", lt + 2)) {\n start = lt + 4;\n if (payload[start] === \">\" || payload.startsWith(\"->\", start)) {\n i = start;\n continue;\n }\n const dashes = payload.indexOf(\"-->\", start);\n const bang = payload.indexOf(\"--!>\", start);\n const end = dashes < 0 || (bang >= 0 && bang < dashes) ? bang : dashes;\n if (end < 0 || payload.slice(start, end).includes(\"zr:1:\")) return true;\n i = end;\n continue;\n }\n if (c === \"/\") {\n // `</` followed by the closing marker's `<` would open a bogus comment.\n if (lt + 2 >= payload.length) return true;\n if (payload[lt + 2] === \">\") {\n i = lt + 3;\n continue;\n }\n start = lt + 2;\n } else if (c === \"!\" || c === \"?\") start = lt + 1;\n else {\n i = lt + 1;\n continue;\n }\n const end = payload.indexOf(\">\", start);\n if (end < 0 || payload.slice(start, end).includes(\"zr:1:\")) return true;\n i = end;\n }\n}\n\n// Returns the index just past the tag's `>`, or -1 when the tag is unterminated\n// or carries a reserved attribute.\nfunction tagEnd(s: string, j: number): number {\n const n = s.length;\n while (j < n && !space.test(s[j]!) && s[j] !== \"/\" && s[j] !== \">\") j++;\n for (;;) {\n while (j < n && (space.test(s[j]!) || s[j] === \"/\")) j++;\n if (j >= n) return -1;\n if (s[j] === \">\") return j + 1;\n const start = j++;\n while (j < n && !nameEnd.test(s[j]!)) j++;\n if (reservedAttributes.has(s.slice(start, j).toLowerCase())) return -1;\n while (j < n && space.test(s[j]!)) j++;\n if (s[j] !== \"=\") continue;\n j++;\n while (j < n && space.test(s[j]!)) j++;\n const quote = s[j];\n if (quote === '\"' || quote === \"'\") {\n const close = s.indexOf(quote, j + 1);\n if (close < 0) return -1;\n j = close + 1;\n } else while (j < n && !unquotedEnd.test(s[j]!)) j++;\n }\n}\n"]}