semajsx 0.1.1 → 0.1.2

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 (103) hide show
  1. package/dist/{computed-BpjqvQu1.mjs → computed-BidG06Lt.mjs} +2 -2
  2. package/dist/{computed-BpjqvQu1.mjs.map → computed-BidG06Lt.mjs.map} +1 -1
  3. package/dist/{document-OGuk9jhK.mjs → document-BOJDaiBc.mjs} +19 -4
  4. package/dist/document-BOJDaiBc.mjs.map +1 -0
  5. package/dist/{document-DFsOtfef.mjs → document-CwHVG_PJ.mjs} +2 -2
  6. package/dist/dom/index.d.mts +68 -3
  7. package/dist/dom/index.d.mts.map +1 -1
  8. package/dist/dom/index.mjs +4 -4
  9. package/dist/dom/jsx-dev-runtime.d.mts +4 -4
  10. package/dist/dom/jsx-dev-runtime.mjs +1 -1
  11. package/dist/dom/jsx-runtime.d.mts +4 -4
  12. package/dist/dom/jsx-runtime.mjs +2 -2
  13. package/dist/{helpers-DrifjCXb.d.mts → helpers-CfRDJgcP.d.mts} +3 -3
  14. package/dist/{helpers-DrifjCXb.d.mts.map → helpers-CfRDJgcP.d.mts.map} +1 -1
  15. package/dist/{index-DS5X3Pvb.d.mts → index-B1pjI-Su.d.mts} +2 -2
  16. package/dist/{index-DS5X3Pvb.d.mts.map → index-B1pjI-Su.d.mts.map} +1 -1
  17. package/dist/index-DC3tthWf.d.mts +81 -0
  18. package/dist/index-DC3tthWf.d.mts.map +1 -0
  19. package/dist/index.d.mts +7 -7
  20. package/dist/index.mjs +5 -5
  21. package/dist/{island-marker-hZdmHMvx.d.mts → island-marker-BJIO07Vj.d.mts} +1 -1
  22. package/dist/island-marker-BJIO07Vj.d.mts.map +1 -0
  23. package/dist/{jsx-CGW4OyqA.d.mts → jsx-fNlLjLou.d.mts} +2 -2
  24. package/dist/{jsx-CGW4OyqA.d.mts.map → jsx-fNlLjLou.d.mts.map} +1 -1
  25. package/dist/{jsx-runtime-DU8DRISG.d.mts → jsx-runtime-BFuFPDzn.d.mts} +3 -3
  26. package/dist/{jsx-runtime-DU8DRISG.d.mts.map → jsx-runtime-BFuFPDzn.d.mts.map} +1 -1
  27. package/dist/jsx-runtime-D9ZNjMJ2.mjs.map +1 -1
  28. package/dist/{jsx-runtime-mBpL8czJ.d.mts → jsx-runtime-DZx2Yv-t.d.mts} +28 -6
  29. package/dist/{jsx-runtime-mBpL8czJ.d.mts.map → jsx-runtime-DZx2Yv-t.d.mts.map} +1 -1
  30. package/dist/lucide-CVtHepGM.mjs +126 -0
  31. package/dist/lucide-CVtHepGM.mjs.map +1 -0
  32. package/dist/{resource-B1IudM8_.d.mts → resource-BQI6AeJ0.d.mts} +23 -3
  33. package/dist/resource-BQI6AeJ0.d.mts.map +1 -0
  34. package/dist/{resource-BjsDAkbG.mjs → resource-DSlXDZZi.mjs} +2 -2
  35. package/dist/{resource-BjsDAkbG.mjs.map → resource-DSlXDZZi.mjs.map} +1 -1
  36. package/dist/signal/index.d.mts +2 -2
  37. package/dist/signal/index.mjs +3 -3
  38. package/dist/{signal-4PgGfydw.mjs → signal-BN8vHXDb.mjs} +1 -1
  39. package/dist/{signal-4PgGfydw.mjs.map → signal-BN8vHXDb.mjs.map} +1 -1
  40. package/dist/{signal-CLsaPA7c.d.mts → signal-BwxUlXKs.d.mts} +1 -1
  41. package/dist/{signal-CLsaPA7c.d.mts.map → signal-BwxUlXKs.d.mts.map} +1 -1
  42. package/dist/{src-CRi0xsNK.mjs → src-BqX3sryB.mjs} +68 -5
  43. package/dist/src-BqX3sryB.mjs.map +1 -0
  44. package/dist/src-DR-EWgVP.mjs +868 -0
  45. package/dist/src-DR-EWgVP.mjs.map +1 -0
  46. package/dist/{src-DEoBG1zB.mjs → src-DUpFNNM_.mjs} +4 -4
  47. package/dist/{src-DEoBG1zB.mjs.map → src-DUpFNNM_.mjs.map} +1 -1
  48. package/dist/{src-BlS3Hc-L.mjs → src-DW3tIczg.mjs} +75 -5
  49. package/dist/src-DW3tIczg.mjs.map +1 -0
  50. package/dist/{src-Jbt_w0hc.mjs → src-Ds9vl42d.mjs} +37 -35
  51. package/dist/src-Ds9vl42d.mjs.map +1 -0
  52. package/dist/{src-iC-NFwTy.mjs → src-DuSN6go_.mjs} +79 -22
  53. package/dist/src-DuSN6go_.mjs.map +1 -0
  54. package/dist/ssg/index.d.mts +4 -182
  55. package/dist/ssg/index.d.mts.map +1 -1
  56. package/dist/ssg/index.mjs +7 -756
  57. package/dist/ssg/index.mjs.map +1 -1
  58. package/dist/ssg/plugins/docs-theme.d.mts +180 -0
  59. package/dist/ssg/plugins/docs-theme.d.mts.map +1 -0
  60. package/dist/ssg/plugins/docs-theme.mjs +2042 -0
  61. package/dist/ssg/plugins/docs-theme.mjs.map +1 -0
  62. package/dist/ssg/plugins/lucide.d.mts +3 -0
  63. package/dist/ssg/plugins/lucide.mjs +7 -0
  64. package/dist/ssr/client.d.mts +3 -3
  65. package/dist/ssr/client.mjs +5 -5
  66. package/dist/ssr/index.d.mts +3 -3
  67. package/dist/ssr/index.d.mts.map +1 -1
  68. package/dist/ssr/index.mjs +6 -5
  69. package/dist/style/index.d.mts +2 -2
  70. package/dist/style/index.d.mts.map +1 -1
  71. package/dist/style/index.mjs +1 -1
  72. package/dist/style/react.d.mts +2 -2
  73. package/dist/style/react.mjs +2 -2
  74. package/dist/style/vue.d.mts +2 -2
  75. package/dist/style/vue.mjs +2 -2
  76. package/dist/terminal/index.d.mts +4 -4
  77. package/dist/terminal/index.mjs +2 -2
  78. package/dist/terminal/jsx-dev-runtime.d.mts +4 -4
  79. package/dist/terminal/jsx-dev-runtime.mjs +1 -1
  80. package/dist/terminal/jsx-runtime.d.mts +4 -4
  81. package/dist/terminal/jsx-runtime.mjs +1 -1
  82. package/dist/{types-DlNR9ZaJ.d.mts → types-BlaUrkq0.d.mts} +2 -2
  83. package/dist/{types-DlNR9ZaJ.d.mts.map → types-BlaUrkq0.d.mts.map} +1 -1
  84. package/dist/types-CGkRxnQB.d.mts +220 -0
  85. package/dist/types-CGkRxnQB.d.mts.map +1 -0
  86. package/dist/{types-Dgj6n-EE.d.mts → types-CZMcXQTW.d.mts} +9 -4
  87. package/dist/types-CZMcXQTW.d.mts.map +1 -0
  88. package/dist/{types-Bjx1Pp14.d.mts → types-D0jRO840.d.mts} +1 -1
  89. package/dist/{types-Bjx1Pp14.d.mts.map → types-D0jRO840.d.mts.map} +1 -1
  90. package/dist/{types-DEi0apQO.d.mts → types-DucvOZQ2.d.mts} +2 -2
  91. package/dist/{types-DEi0apQO.d.mts.map → types-DucvOZQ2.d.mts.map} +1 -1
  92. package/dist/{utils-BrGmTgfG.mjs → utils-DbTAs943.mjs} +1 -1
  93. package/dist/{utils-BrGmTgfG.mjs.map → utils-DbTAs943.mjs.map} +1 -1
  94. package/package.json +30 -2
  95. package/dist/document-OGuk9jhK.mjs.map +0 -1
  96. package/dist/island-marker-hZdmHMvx.d.mts.map +0 -1
  97. package/dist/jsx-runtime-D2B2BK8X.mjs +0 -4
  98. package/dist/resource-B1IudM8_.d.mts.map +0 -1
  99. package/dist/src-BlS3Hc-L.mjs.map +0 -1
  100. package/dist/src-CRi0xsNK.mjs.map +0 -1
  101. package/dist/src-Jbt_w0hc.mjs.map +0 -1
  102. package/dist/src-iC-NFwTy.mjs.map +0 -1
  103. package/dist/types-Dgj6n-EE.d.mts.map +0 -1
@@ -0,0 +1,220 @@
1
+ import { d as VNode, t as Component } from "./types-CZMcXQTW.mjs";
2
+ import { z } from "zod";
3
+
4
+ //#region ../ssg/src/types.d.ts
5
+ /**
6
+ * Infer a registry type from an array of collections
7
+ * Maps collection names to their data types
8
+ */
9
+ type InferCollections<T extends readonly Collection[]> = { [K in T[number] as K["name"]]: K extends Collection<infer D> ? D : unknown };
10
+ interface CollectionEntry<T = unknown> {
11
+ /** Unique identifier within the collection */
12
+ id: string;
13
+ /** URL-friendly slug */
14
+ slug: string;
15
+ /** Validated frontmatter data */
16
+ data: T;
17
+ /** Raw content body (markdown/mdx) */
18
+ body: string;
19
+ /** Render the content to JSX */
20
+ render: () => Promise<{
21
+ Content: () => VNode;
22
+ }>;
23
+ }
24
+ interface ChangeSet<T = unknown> {
25
+ /** Cursor for next incremental fetch */
26
+ cursor: string;
27
+ /** Newly added entries */
28
+ added: CollectionEntry<T>[];
29
+ /** Updated entries */
30
+ updated: CollectionEntry<T>[];
31
+ /** Deleted entry IDs */
32
+ deleted: string[];
33
+ }
34
+ type WatchCallback<T = unknown> = (changes: ChangeSet<T>) => void;
35
+ interface CollectionSource<T = unknown> {
36
+ /** Unique identifier for this source */
37
+ id: string;
38
+ /** Get all entries from this source */
39
+ getEntries(): Promise<CollectionEntry<T>[]>;
40
+ /** Get a single entry by ID */
41
+ getEntry(id: string): Promise<CollectionEntry<T> | null>;
42
+ /** Watch for changes (optional) */
43
+ watch?(callback: WatchCallback<T>): () => void;
44
+ /** Get incremental changes since cursor (optional) */
45
+ getChanges?(since: string): Promise<ChangeSet<T>>;
46
+ }
47
+ interface CollectionConfig<T extends z.ZodType = z.ZodType> {
48
+ /** Collection name */
49
+ name: string;
50
+ /** Data source (returns raw entries, validated against schema later) */
51
+ source: CollectionSource<unknown>;
52
+ /** Zod schema for validation */
53
+ schema: T;
54
+ }
55
+ interface Collection<T = unknown> {
56
+ name: string;
57
+ source: CollectionSource<unknown>;
58
+ schema: z.ZodType;
59
+ /** Type-only field for inference */
60
+ _outputType?: T;
61
+ }
62
+ interface StaticPath<P = Record<string, string>> {
63
+ params: P;
64
+ props?: Record<string, unknown>;
65
+ }
66
+ interface RouteConfig<TRegistry extends Record<string, unknown> = Record<string, unknown>> {
67
+ /** Route path pattern (e.g., '/blog/:slug') */
68
+ path: string;
69
+ /** Component to render. Props are provided dynamically by the route config. */
70
+ component: (props: any) => VNode;
71
+ /** Static props for the route */
72
+ props?: Record<string, unknown> | ((ssg: SSGInstance<TRegistry>) => Promise<Record<string, unknown>>);
73
+ /** Generate static paths for dynamic routes */
74
+ getStaticPaths?: (ssg: SSGInstance<TRegistry>) => Promise<StaticPath[]>;
75
+ }
76
+ interface MDXConfig {
77
+ /** Remark plugins */
78
+ remarkPlugins?: unknown[];
79
+ /** Rehype plugins */
80
+ rehypePlugins?: unknown[];
81
+ /** Component mapping for MDX */
82
+ components?: Record<string, Component>;
83
+ }
84
+ /**
85
+ * Raw HTML VNode that can be used directly in JSX or converted to string
86
+ */
87
+ declare class RawHTML {
88
+ readonly html: string;
89
+ readonly type = "div";
90
+ readonly props: {
91
+ dangerouslySetInnerHTML: {
92
+ __html: string;
93
+ };
94
+ };
95
+ readonly children: never[];
96
+ constructor(html: string);
97
+ toString(): string;
98
+ }
99
+ interface DocumentProps {
100
+ /** Rendered page content (VNode with toString) */
101
+ children: RawHTML;
102
+ /** Page title */
103
+ title?: string;
104
+ /** Base URL path */
105
+ base: string;
106
+ /** Route path */
107
+ path: string;
108
+ /** Route props */
109
+ props: Record<string, unknown>;
110
+ /** Script tags for islands (as RawHTML) */
111
+ scripts?: RawHTML;
112
+ /** CSS stylesheet paths */
113
+ css?: string[];
114
+ }
115
+ type DocumentTemplate = (props: DocumentProps) => VNode;
116
+ /**
117
+ * Partial SSG config that a plugin's config() hook can return.
118
+ * Each field has a defined merge strategy:
119
+ * - mdx: merge (concat arrays, merge component objects)
120
+ * - document: override (last writer wins)
121
+ * - routes: concat
122
+ * - collections: concat
123
+ */
124
+ interface SSGPluginConfig {
125
+ mdx?: Partial<MDXConfig>;
126
+ document?: DocumentTemplate;
127
+ routes?: RouteConfig[];
128
+ collections?: readonly Collection[];
129
+ }
130
+ interface SSGPlugin {
131
+ /** Plugin name for identification and debugging */
132
+ name: string;
133
+ /** Plugin ordering: 'pre' runs before normal plugins, 'post' runs after */
134
+ enforce?: "pre" | "post";
135
+ /**
136
+ * Modify SSG config before it is resolved.
137
+ * Return partial config to merge.
138
+ * Called in plugin order: enforce:'pre' → normal → enforce:'post' → user config.
139
+ */
140
+ config?(config: SSGConfig): SSGPluginConfig | void;
141
+ /** Called after config is fully resolved. Read-only inspection. */
142
+ configResolved?(config: SSGConfig): void;
143
+ /** Called before build starts */
144
+ buildStart?(): void | Promise<void>;
145
+ /** Called after build completes */
146
+ buildEnd?(result: BuildResult): void | Promise<void>;
147
+ }
148
+ interface SSGConfig<TCollections extends readonly Collection[] = Collection[], TRegistry extends Record<string, unknown> = InferCollections<TCollections>> {
149
+ /** Output directory for built files */
150
+ outDir: string;
151
+ /** Root directory for resolving relative paths (defaults to script location) */
152
+ rootDir?: string;
153
+ /** Base URL path */
154
+ base?: string;
155
+ /** Collections to include */
156
+ collections?: TCollections;
157
+ /** Route definitions */
158
+ routes?: RouteConfig<TRegistry>[];
159
+ /** Plugins that contribute remark/rehype plugins and components.
160
+ * Plugin factories may return arrays (Vite-style); nested arrays are flattened. */
161
+ plugins?: (SSGPlugin | SSGPlugin[])[];
162
+ /** MDX configuration (merged after plugins, takes precedence) */
163
+ mdx?: MDXConfig;
164
+ /** Custom document template */
165
+ document?: DocumentTemplate;
166
+ }
167
+ interface BuildState {
168
+ /** Cursor for each collection */
169
+ cursors: Record<string, string>;
170
+ /** Content hash for each page */
171
+ pageHashes: Record<string, string>;
172
+ /** Last build timestamp */
173
+ timestamp: number;
174
+ }
175
+ interface BuildResult {
176
+ /** New build state for incremental builds */
177
+ state: BuildState;
178
+ /** Paths that were built */
179
+ paths: string[];
180
+ /** Build statistics */
181
+ stats: {
182
+ added: number;
183
+ updated: number;
184
+ deleted: number;
185
+ unchanged: number;
186
+ };
187
+ }
188
+ interface BuildOptions {
189
+ /** Enable incremental build */
190
+ incremental?: boolean;
191
+ /** Previous build state */
192
+ state?: BuildState;
193
+ /** Only build specific collections */
194
+ collections?: string[];
195
+ }
196
+ interface WatchOptions {
197
+ /** Callback when rebuild completes */
198
+ onRebuild?: (result: BuildResult) => void;
199
+ /** Callback on error */
200
+ onError?: (error: Error) => void;
201
+ }
202
+ interface Watcher {
203
+ /** Stop watching */
204
+ close(): void;
205
+ }
206
+ interface SSGInstance<TRegistry extends Record<string, unknown> = Record<string, unknown>> {
207
+ /** Get the root directory for resolving paths */
208
+ getRootDir(): string;
209
+ /** Get all entries from a collection */
210
+ getCollection<K extends keyof TRegistry & string>(name: K): Promise<CollectionEntry<TRegistry[K]>[]>;
211
+ /** Get a single entry from a collection */
212
+ getEntry<K extends keyof TRegistry & string>(name: K, id: string): Promise<CollectionEntry<TRegistry[K]> | null>;
213
+ /** Build the static site */
214
+ build(options?: BuildOptions): Promise<BuildResult>;
215
+ /** Watch for changes and rebuild */
216
+ watch(options?: WatchOptions): Watcher;
217
+ }
218
+ //#endregion
219
+ export { Watcher as S, SSGPlugin as _, Collection as a, WatchCallback as b, CollectionSource as c, InferCollections as d, MDXConfig as f, SSGInstance as g, SSGConfig as h, ChangeSet as i, DocumentProps as l, RouteConfig as m, BuildResult as n, CollectionConfig as o, RawHTML as p, BuildState as r, CollectionEntry as s, BuildOptions as t, DocumentTemplate as u, SSGPluginConfig as v, WatchOptions as x, StaticPath as y };
220
+ //# sourceMappingURL=types-CGkRxnQB.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-CGkRxnQB.d.mts","names":[],"sources":["../../ssg/src/types.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as WritableSignal, n as ReadableSignal } from "./signal-CLsaPA7c.mjs";
1
+ import { i as WritableSignal, n as ReadableSignal } from "./signal-BwxUlXKs.mjs";
2
2
 
3
3
  //#region ../core/src/types.d.ts
4
4
  /**
@@ -10,10 +10,15 @@ declare const Fragment: symbol;
10
10
  */
11
11
  declare const Portal: symbol;
12
12
  /**
13
+ * Special VNode type for forward support
14
+ * Forward merges its props onto its single child element without producing a DOM node
15
+ */
16
+ declare const Forward: symbol;
17
+ /**
13
18
  * VNode types
14
19
  * - The runtime VNode tree always resolves to these `type` values
15
20
  */
16
- type VNodeType = string | Component<any> | typeof Fragment | typeof Portal;
21
+ type VNodeType = string | Component<any> | typeof Fragment | typeof Portal | typeof Forward;
17
22
  /**
18
23
  * VNode: The basic unit of the runtime render tree
19
24
  * - `type`: the element/component type
@@ -96,5 +101,5 @@ type WithKey<T> = T & {
96
101
  key?: string | number;
97
102
  };
98
103
  //#endregion
99
- export { ContextProvide as a, Portal as c, VNodeType as d, WithKey as f, ContextProps as i, Ref as l, ComponentAPI as n, Fragment as o, WithSignals as p, Context as r, JSXNode as s, Component as t, VNode as u };
100
- //# sourceMappingURL=types-Dgj6n-EE.d.mts.map
104
+ export { ContextProvide as a, JSXNode as c, VNode as d, VNodeType as f, ContextProps as i, Portal as l, WithSignals as m, ComponentAPI as n, Forward as o, WithKey as p, Context as r, Fragment as s, Component as t, Ref as u };
105
+ //# sourceMappingURL=types-CZMcXQTW.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-CZMcXQTW.d.mts","names":[],"sources":["../../core/src/types.ts"],"mappings":";;;;;AAKA;cAAa,QAAA;;;;cAKA,MAAA;;;;;cAMA,OAAA;;;;;KAMD,SAAA,YAAqB,SAAA,eAAwB,QAAA,UAAkB,MAAA,UAAgB,OAAA;;;;;;;UAQ1E,KAAA;EACf,IAAA,EAAM,SAAA;EACN,KAAA,EAAO,MAAA;EACP,QAAA,EAAU,KAAA;EACV,GAAA;AAAA;;;AAJF;;KAWY,YAAA;;;;;KAMA,OAAA,GACR,KAAA,GACA,YAAA,GACA,QAAA,CAAS,OAAA,IACT,cAAA,CAAe,OAAA,IACf,OAAA,CAAQ,OAAA,IACR,qBAAA,CAAsB,OAAA;;;;;KAMd,SAAA,aAAsB,KAAA,EAAO,CAAA,EAAG,GAAA,GAAM,YAAA,KAAiB,OAAA;;;;UAKlD,YAAA;EAvBjB;;;;;EA6BE,MAAA,IAAU,OAAA,EAAS,OAAA,CAAQ,CAAA,IAAK,CAAA;AAAA;;;;;;;;KAWtB,GAAA,MAAS,cAAA,CAAe,CAAA,aAAc,QAAA,EAAU,CAAA;;;;;;;KAShD,OAAA;EAAwB,MAAA,GAAS,CAAA;AAAA;;;;KAKjC,cAAA,aAA2B,OAAA,CAAQ,CAAA,GAAI,CAAA;;;;UAKlC,YAAA;EAGf,OAAA,EAAS,cAAA,GAAiB,cAAA;EAC1B,QAAA,GAAW,OAAA;AAAA;;;;KAMD,QAAA,MAAc,CAAA,GAAI,cAAA,CAAe,CAAA;;;;;KAMjC,WAAA,oBACE,CAAA,GAAI,CAAA,yBACZ,CAAA,CAAE,CAAA,IACF,CAAA,sBACE,CAAA,CAAE,CAAA,IACF,CAAA,CAAE,CAAA,eAAe,IAAA,mBACf,CAAA,CAAE,CAAA,IACF,QAAA,CAAS,CAAA,CAAE,CAAA;;;;KAMT,OAAA,MAAa,CAAA;EACvB,GAAA;AAAA"}
@@ -88,4 +88,4 @@ interface TerminalRoot extends TerminalNodeBase {
88
88
  type TerminalNode = TerminalElement | TerminalText | TerminalRoot;
89
89
  //#endregion
90
90
  export { TerminalText as a, TerminalStyle as i, TerminalNode as n, TerminalRoot as r, TerminalElement as t };
91
- //# sourceMappingURL=types-Bjx1Pp14.d.mts.map
91
+ //# sourceMappingURL=types-D0jRO840.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-Bjx1Pp14.d.mts","names":[],"sources":["../../terminal/src/types.ts"],"mappings":";;;KAEY,YAAA,GAAe,UAAA,QAAkB,IAAA,CAAK,IAAA,CAAK,MAAA;;AAAvD;;KAKY,gBAAA;;;;UAKK,aAAA;EACf,aAAA;EACA,cAAA;EACA,UAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,QAAA;EACA,SAAA;EACA,MAAA;EACA,UAAA;EACA,WAAA;EACA,SAAA;EACA,YAAA;EACA,YAAA;EACA,WAAA;EACA,OAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,aAAA;EACA,aAAA;EACA,YAAA;EACA,MAAA;EACA,WAAA;EACA,KAAA;EACA,eAAA;EACA,IAAA;EACA,MAAA;EACA,SAAA;EACA,aAAA;EACA,GAAA;AAAA;;;;UAMe,gBAAA;EACf,IAAA,EAAM,gBAAA;EACN,QAAA,GAAW,YAAA;EACX,MAAA,EAAQ,YAAA;EACR,QAAA,EAAU,YAAA;EACV,CAAA;EACA,CAAA;EACA,KAAA;EACA,MAAA;AAAA;AARF;;;AAAA,UAciB,eAAA,SAAwB,gBAAA;EACvC,IAAA;EACA,OAAA;EACA,KAAA,EAAO,aAAA;EACP,KAAA,EAAO,MAAA;AAAA;;;;UAMQ,YAAA,SAAqB,gBAAA;EACpC,IAAA;EACA,OAAA;AAAA;;;;UAMe,YAAA,SAAqB,gBAAA;EACpC,IAAA;EACA,MAAA,EAAQ,MAAA,CAAO,WAAA;AAAA;AApBjB;;;AAAA,KA0BY,YAAA,GAAe,eAAA,GAAkB,YAAA,GAAe,YAAA"}
1
+ {"version":3,"file":"types-D0jRO840.d.mts","names":[],"sources":["../../terminal/src/types.ts"],"mappings":";;;KAEY,YAAA,GAAe,UAAA,QAAkB,IAAA,CAAK,IAAA,CAAK,MAAA;;AAAvD;;KAKY,gBAAA;;;;UAKK,aAAA;EACf,aAAA;EACA,cAAA;EACA,UAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,QAAA;EACA,SAAA;EACA,MAAA;EACA,UAAA;EACA,WAAA;EACA,SAAA;EACA,YAAA;EACA,YAAA;EACA,WAAA;EACA,OAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,aAAA;EACA,aAAA;EACA,YAAA;EACA,MAAA;EACA,WAAA;EACA,KAAA;EACA,eAAA;EACA,IAAA;EACA,MAAA;EACA,SAAA;EACA,aAAA;EACA,GAAA;AAAA;;;;UAMe,gBAAA;EACf,IAAA,EAAM,gBAAA;EACN,QAAA,GAAW,YAAA;EACX,MAAA,EAAQ,YAAA;EACR,QAAA,EAAU,YAAA;EACV,CAAA;EACA,CAAA;EACA,KAAA;EACA,MAAA;AAAA;AARF;;;AAAA,UAciB,eAAA,SAAwB,gBAAA;EACvC,IAAA;EACA,OAAA;EACA,KAAA,EAAO,aAAA;EACP,KAAA,EAAO,MAAA;AAAA;;;;UAMQ,YAAA,SAAqB,gBAAA;EACpC,IAAA;EACA,OAAA;AAAA;;;;UAMe,YAAA,SAAqB,gBAAA;EACpC,IAAA;EACA,MAAA,EAAQ,MAAA,CAAO,WAAA;AAAA;AApBjB;;;AAAA,KA0BY,YAAA,GAAe,eAAA,GAAkB,YAAA,GAAe,YAAA"}
@@ -1,4 +1,4 @@
1
- import { n as ReadableSignal } from "./types-DlNR9ZaJ.mjs";
1
+ import { n as ReadableSignal } from "./types-BlaUrkq0.mjs";
2
2
 
3
3
  //#region ../style/src/types.d.ts
4
4
  /**
@@ -61,4 +61,4 @@ interface RegistryOptions {
61
61
  }
62
62
  //#endregion
63
63
  export { SignalBindingDef as a, RegistryOptions as i, ClassRefs as n, StyleToken as o, InjectOptions as r, ClassRef as t };
64
- //# sourceMappingURL=types-DEi0apQO.d.mts.map
64
+ //# sourceMappingURL=types-DucvOZQ2.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-DEi0apQO.d.mts","names":[],"sources":["../../style/src/types.ts"],"mappings":";;;;;;UASiB,QAAA;EAUjB;EAAA,SARW,EAAA;;EAET,QAAA;AAAA;;;;KAMU,SAAA,iDACK,CAAA,WAAY,QAAA;;AAO7B;;;UAAiB,gBAAA;;EAEf,MAAA,EAAQ,cAAA;;EAER,KAAA;AAAA;AAUF;;;;;;;AAAA,UAAiB,UAAA;;WAEN,MAAA;;WAEA,CAAA;EAYX;EAAA,SAVW,aAAA;;WAEA,aAAA,GAAgB,gBAAA;;EAEzB,QAAA;AAAA;;;AAcF;UARiB,aAAA;;EAEf,MAAA,GAAS,OAAA,GAAU,UAAA;AAAA;;;;UAMJ,eAAA;EAIf;EAFA,MAAA,GAAS,OAAA,GAAU,UAAA;;EAEnB,MAAA;AAAA"}
1
+ {"version":3,"file":"types-DucvOZQ2.d.mts","names":[],"sources":["../../style/src/types.ts"],"mappings":";;;;;;UASiB,QAAA;EAUjB;EAAA,SARW,EAAA;;EAET,QAAA;AAAA;;;;KAMU,SAAA,iDACK,CAAA,WAAY,QAAA;;AAO7B;;;UAAiB,gBAAA;;EAEf,MAAA,EAAQ,cAAA;;EAER,KAAA;AAAA;AAUF;;;;;;;AAAA,UAAiB,UAAA;;WAEN,MAAA;;WAEA,CAAA;EAYX;EAAA,SAVW,aAAA;;WAEA,aAAA,GAAgB,gBAAA;;EAEzB,QAAA;AAAA;;;AAcF;UARiB,aAAA;;EAEf,MAAA,GAAS,OAAA,GAAU,UAAA;AAAA;;;;UAMJ,eAAA;EAIf;EAFA,MAAA,GAAS,OAAA,GAAU,UAAA;;EAEnB,MAAA;AAAA"}
@@ -26,4 +26,4 @@ function unwrap(value) {
26
26
 
27
27
  //#endregion
28
28
  export { unwrap as n, isSignal as t };
29
- //# sourceMappingURL=utils-BrGmTgfG.mjs.map
29
+ //# sourceMappingURL=utils-DbTAs943.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils-BrGmTgfG.mjs","names":[],"sources":["../../signal/src/utils.ts"],"sourcesContent":["import type { ReadableSignal, MaybeSignal } from \"./types\";\n\n/**\n * Check if a value is a signal\n *\n * Uses duck typing to check for the minimal signal interface:\n * - has a `value` property\n * - has a `subscribe` method\n */\nexport function isSignal<T = unknown>(value: unknown): value is ReadableSignal<T> {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"subscribe\" in value &&\n typeof value.subscribe === \"function\"\n );\n}\n\n/**\n * Unwrap a signal or return the value as-is\n *\n * Useful for accepting both static values and signals:\n * @example\n * ```ts\n * function Component(props: { count: MaybeSignal<number> }) {\n * const value = unwrap(props.count); // Always get the current value\n * }\n * ```\n */\nexport function unwrap<T>(value: MaybeSignal<T>): T {\n return isSignal(value) ? value.value : value;\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,SAAsB,OAA4C;AAChF,QACE,SAAS,QACT,OAAO,UAAU,YACjB,WAAW,SACX,eAAe,SACf,OAAO,MAAM,cAAc;;;;;;;;;;;;;AAe/B,SAAgB,OAAU,OAA0B;AAClD,QAAO,SAAS,MAAM,GAAG,MAAM,QAAQ"}
1
+ {"version":3,"file":"utils-DbTAs943.mjs","names":[],"sources":["../../signal/src/utils.ts"],"sourcesContent":["import type { ReadableSignal, MaybeSignal } from \"./types\";\n\n/**\n * Check if a value is a signal\n *\n * Uses duck typing to check for the minimal signal interface:\n * - has a `value` property\n * - has a `subscribe` method\n */\nexport function isSignal<T = unknown>(value: unknown): value is ReadableSignal<T> {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"subscribe\" in value &&\n typeof value.subscribe === \"function\"\n );\n}\n\n/**\n * Unwrap a signal or return the value as-is\n *\n * Useful for accepting both static values and signals:\n * @example\n * ```ts\n * function Component(props: { count: MaybeSignal<number> }) {\n * const value = unwrap(props.count); // Always get the current value\n * }\n * ```\n */\nexport function unwrap<T>(value: MaybeSignal<T>): T {\n return isSignal(value) ? value.value : value;\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,SAAsB,OAA4C;AAChF,QACE,SAAS,QACT,OAAO,UAAU,YACjB,WAAW,SACX,eAAe,SACf,OAAO,MAAM,cAAc;;;;;;;;;;;;;AAe/B,SAAgB,OAAU,OAA0B;AAClD,QAAO,SAAS,MAAM,GAAG,MAAM,QAAQ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "semajsx",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A signal-based reactive JSX runtime for building modern web applications",
5
5
  "keywords": [
6
6
  "framework",
@@ -47,6 +47,14 @@
47
47
  "source": "./src/ssg/index.ts",
48
48
  "default": "./dist/ssg/index.mjs"
49
49
  },
50
+ "./ssg/plugins/docs-theme": {
51
+ "source": "./src/ssg/plugins/docs-theme.ts",
52
+ "default": "./dist/ssg/plugins/docs-theme.mjs"
53
+ },
54
+ "./ssg/plugins/lucide": {
55
+ "source": "./src/ssg/plugins/lucide.ts",
56
+ "default": "./dist/ssg/plugins/lucide.mjs"
57
+ },
50
58
  "./ssr": {
51
59
  "source": "./src/ssr/index.ts",
52
60
  "default": "./dist/ssr/index.mjs"
@@ -86,7 +94,27 @@
86
94
  "./package.json": "./package.json"
87
95
  },
88
96
  "publishConfig": {
89
- "access": "public"
97
+ "access": "public",
98
+ "exports": {
99
+ ".": "./dist/index.mjs",
100
+ "./dom": "./dist/dom/index.mjs",
101
+ "./dom/jsx-dev-runtime": "./dist/dom/jsx-dev-runtime.mjs",
102
+ "./dom/jsx-runtime": "./dist/dom/jsx-runtime.mjs",
103
+ "./signal": "./dist/signal/index.mjs",
104
+ "./ssg": "./dist/ssg/index.mjs",
105
+ "./ssg/plugins/docs-theme": "./dist/ssg/plugins/docs-theme.mjs",
106
+ "./ssg/plugins/lucide": "./dist/ssg/plugins/lucide.mjs",
107
+ "./ssr": "./dist/ssr/index.mjs",
108
+ "./ssr/client": "./dist/ssr/client.mjs",
109
+ "./style": "./dist/style/index.mjs",
110
+ "./style/react": "./dist/style/react.mjs",
111
+ "./style/vue": "./dist/style/vue.mjs",
112
+ "./tailwind": "./dist/tailwind/index.mjs",
113
+ "./terminal": "./dist/terminal/index.mjs",
114
+ "./terminal/jsx-dev-runtime": "./dist/terminal/jsx-dev-runtime.mjs",
115
+ "./terminal/jsx-runtime": "./dist/terminal/jsx-runtime.mjs",
116
+ "./package.json": "./package.json"
117
+ }
90
118
  },
91
119
  "scripts": {
92
120
  "build": "tsdown",
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-OGuk9jhK.mjs","names":[],"sources":["../../ssr/src/document.tsx"],"sourcesContent":["/** @jsxImportSource @semajsx/dom */\n\nimport { Fragment } from \"@semajsx/core\";\nimport type { DocumentTemplate } from \"./shared/types\";\n\n/**\n * Default HTML document template\n *\n * This is a simple, production-ready HTML5 document template.\n * You can customize it by providing your own document template to the router.\n *\n * @example\n * ```tsx\n * const router = createViteRouter(routes, {\n * document: DefaultDocument,\n * title: \"My App\" // Required if using DefaultDocument\n * });\n * ```\n */\nexport const DefaultDocument: DocumentTemplate = ({ children, scripts, css, title }) => (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n {title && <title>{title}</title>}\n {css.map((href) => (\n <link key={href} rel=\"stylesheet\" href={href} />\n ))}\n </head>\n <body>\n {children}\n {scripts}\n </body>\n </html>\n);\n\n/**\n * Render a document VNode to a complete HTML string\n * Prepends <!DOCTYPE html> to the rendered output\n *\n * @param documentVNode - The document VNode (should be <html> element)\n * @returns Complete HTML string with doctype\n */\nexport function renderDocument(documentVNode: any): string {\n // Import renderToString from render.ts\n // We can't import it directly to avoid circular dependencies\n // So we use a simple HTML renderer for the document shell\n\n const html = renderDocumentVNode(documentVNode);\n return `<!DOCTYPE html>\\n${html}`;\n}\n\n/**\n * Simple HTML renderer for document structure\n * This handles the outer HTML/head/body structure without islands\n */\nfunction renderDocumentVNode(vnode: any): string {\n if (vnode == null) {\n return \"\";\n }\n\n if (typeof vnode === \"string\" || typeof vnode === \"number\") {\n const str = String(vnode);\n // Check if it's already rendered HTML (starts with < or contains HTML tags)\n if (str.startsWith(\"<\") || str.includes(\"</\")) {\n return str;\n }\n return escapeHTML(str);\n }\n\n if (typeof vnode === \"boolean\") {\n return \"\";\n }\n\n if (Array.isArray(vnode)) {\n return vnode.map((child) => renderDocumentVNode(child)).join(\"\");\n }\n\n if (typeof vnode !== \"object\" || !(\"type\" in vnode)) {\n return \"\";\n }\n\n const { type, props, children } = vnode;\n\n // Handle dangerouslySetInnerHTML (for raw HTML injection)\n if (props?.dangerouslySetInnerHTML?.__html) {\n return props.dangerouslySetInnerHTML.__html;\n }\n\n // Handle Fragment (Symbol type)\n if (type === Fragment) {\n return (children || []).map((child: any) => renderDocumentVNode(child)).join(\"\");\n }\n\n // Handle special VNode types\n if (typeof type === \"string\") {\n // Handle internal node types like #text, #signal\n if (type.startsWith(\"#\")) {\n if (type === \"#text\") {\n const value = props?.nodeValue ?? \"\";\n // Check if it's already rendered HTML\n if (typeof value === \"string\" && (value.startsWith(\"<\") || value.includes(\"</\"))) {\n return value;\n }\n return escapeHTML(String(value));\n }\n // For #signal and other special types, render children\n return (children || []).map((child: any) => renderDocumentVNode(child)).join(\"\");\n }\n return renderElement(type, props, children);\n }\n\n if (typeof type === \"function\") {\n const result = type(props || {});\n return renderDocumentVNode(result);\n }\n\n return \"\";\n}\n\n/**\n * Render an HTML element\n */\nfunction renderElement(tag: string, props: any, children: any[]): string {\n const attrs = renderAttributes(props || {});\n\n // Self-closing tags\n const selfClosing = [\"meta\", \"link\", \"br\", \"hr\", \"img\", \"input\"];\n if (selfClosing.includes(tag)) {\n return `<${tag}${attrs} />`;\n }\n\n const childrenHTML = (children || []).map((child) => renderDocumentVNode(child)).join(\"\");\n\n return `<${tag}${attrs}>${childrenHTML}</${tag}>`;\n}\n\n/**\n * Render attributes\n */\nfunction renderAttributes(props: Record<string, any>): string {\n const attrs: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" || key === \"key\" || key === \"ref\" || key === \"dangerouslySetInnerHTML\") {\n continue;\n }\n\n if (value == null || value === false) {\n continue;\n }\n\n // Boolean attributes\n if (value === true) {\n attrs.push(key);\n continue;\n }\n\n // Map React attribute names to HTML\n const attrName =\n key === \"className\"\n ? \"class\"\n : key === \"htmlFor\"\n ? \"for\"\n : key === \"charSet\"\n ? \"charset\"\n : key;\n\n attrs.push(`${attrName}=\"${escapeHTML(String(value))}\"`);\n }\n\n return attrs.length > 0 ? \" \" + attrs.join(\" \") : \"\";\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHTML(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"island-marker-hZdmHMvx.d.mts","names":[],"sources":["../../core/src/shared/island-marker.ts"],"mappings":";;AAIA;;;cAAa,aAAA"}
@@ -1,4 +0,0 @@
1
- import { _ as Fragment, a as jsxs, i as jsx } from "./src-BlS3Hc-L.mjs";
2
- import "./jsx-runtime-D9ZNjMJ2.mjs";
3
-
4
- export { Fragment, jsx, jsxs };
@@ -1 +0,0 @@
1
- {"version":3,"file":"resource-B1IudM8_.d.mts","names":[],"sources":["../../ssr/src/shared/types.ts","../../ssr/src/client/resource.ts"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-BlS3Hc-L.mjs","names":[],"sources":["../../core/src/types.ts","../../core/src/vnode.ts","../../core/src/shared/island-marker.ts","../../core/src/context.ts","../../core/src/helpers.ts","../../core/src/jsx.ts","../../core/src/component.ts","../../core/src/render-core.ts"],"sourcesContent":["import type { ReadableSignal, WritableSignal } from \"./signal\";\n\n/**\n * Special VNode type for fragment support\n */\nexport const Fragment: symbol = Symbol.for(\"semajsx.fragment\");\n\n/**\n * Special VNode type for portal support\n */\nexport const Portal: symbol = Symbol.for(\"semajsx.portal\");\n\n/**\n * VNode types\n * - The runtime VNode tree always resolves to these `type` values\n */\nexport type VNodeType = string | Component<any> | typeof Fragment | typeof Portal;\n\n/**\n * VNode: The basic unit of the runtime render tree\n * - `type`: the element/component type\n * - `props`: attributes or props passed to the node (may be null)\n * - `children`: resolved child nodes (always normalized to VNode[] at render time)\n */\nexport interface VNode {\n type: VNodeType;\n props: Record<string, any> | null;\n children: VNode[];\n key?: string | number | null;\n}\n\n/**\n * Primitive values allowed in JSX\n * - These are normalized during VNode construction\n */\nexport type JSXPrimitive = string | number | boolean | null | undefined;\n\n/**\n * A JSXNode represents any valid \"JSX expression result\"\n * - Could be a raw VNode/primitive, or wrapped in a reactive/async container\n */\nexport type JSXNode =\n | VNode\n | JSXPrimitive\n | Iterable<JSXNode>\n | ReadableSignal<JSXNode>\n | Promise<JSXNode>\n | AsyncIterableIterator<JSXNode>;\n\n/**\n * Component type\n * - Optional `ctx` parameter allows passing in custom API/runtime helpers\n */\nexport type Component<P = any> = (props: P, ctx?: ComponentAPI) => JSXNode;\n\n/**\n * ComponentAPI - Runtime API available to components via second parameter\n */\nexport interface ComponentAPI {\n /**\n * Inject a context value\n * @param context - The context to inject\n * @returns The current value of the context, or undefined if not provided\n */\n inject<T>(context: Context<T>): T | undefined;\n}\n\n/**\n * Ref types\n */\n\n/**\n * Ref - can be a WritableSignal or a callback function\n * This allows both reactive refs and imperative refs\n */\nexport type Ref<T> = WritableSignal<T | null> | ((instance: T | null) => void);\n\n/**\n * Context types\n */\n\n/**\n * Context - a typed Symbol for identifying context\n */\nexport type Context<T> = symbol & { __type?: T };\n\n/**\n * Context provide entry: [Context, value]\n */\nexport type ContextProvide<T = any> = [Context<T>, T];\n\n/**\n * Context component props - supports single or multiple context provides\n */\nexport interface ContextProps {\n // Single context: [ThemeContext, theme]\n // Multiple contexts: [[ThemeContext, theme], [UserContext, user]]\n provide: ContextProvide | ContextProvide[];\n children?: JSXNode;\n}\n\n/**\n * Helper type to allow Signal values for any attribute\n */\nexport type SignalOr<T> = T | ReadableSignal<T>;\n\n/**\n * Makes all properties in T accept Signal values\n * Excludes event handlers (functions) and children\n */\nexport type WithSignals<T> = {\n [K in keyof T]: K extends `on${string}`\n ? T[K] // Event handlers don't need Signal wrapper\n : K extends \"children\"\n ? T[K] // Children handled separately\n : T[K] extends (...args: any[]) => any\n ? T[K] // Other functions don't need Signal wrapper\n : SignalOr<T[K]>;\n};\n\n/**\n * Adds key property to element attributes for list reconciliation\n */\nexport type WithKey<T> = T & {\n key?: string | number;\n};\n","import type { JSXNode, VNode, VNodeType } from \"./types\";\nimport type { Signal } from \"@semajsx/signal\";\nimport { Fragment } from \"./types\";\nimport { isSignal } from \"@semajsx/signal\";\n\n/**\n * Create a VNode (Virtual Node)\n */\nexport function h(\n type: VNodeType,\n props: Record<string, any> | null,\n ...children: JSXNode[]\n): VNode {\n return {\n type,\n props: props || {},\n children: normalizeChildren(children),\n key: props?.key,\n };\n}\n\n/**\n * Create a text VNode\n */\nexport function createTextVNode(text: string | number): VNode {\n return {\n type: \"#text\",\n props: { nodeValue: String(text) },\n children: [],\n };\n}\n\n/**\n * Create a signal VNode wrapper\n */\nexport function createSignalVNode(signal: Signal<unknown>): VNode {\n return {\n type: \"#signal\",\n props: { signal },\n children: [],\n };\n}\n\n/**\n * Normalize children into an array of VNodes\n */\nfunction normalizeChildren(children: JSXNode[]): VNode[] {\n const result: VNode[] = [];\n\n for (const child of children) {\n if (child == null || typeof child === \"boolean\") {\n // Skip nullish and boolean values\n continue;\n }\n\n if (Array.isArray(child)) {\n // Recursively flatten arrays\n result.push(...normalizeChildren(child));\n } else if (typeof child === \"string\" || typeof child === \"number\") {\n // Convert primitives to text nodes\n result.push(createTextVNode(child));\n } else if (isSignal(child)) {\n // Wrap signals in special signal nodes\n result.push(createSignalVNode(child));\n } else if (isVNode(child)) {\n // Already a VNode\n result.push(child);\n } else {\n // Unknown type, skip\n console.warn(\"Unknown child type:\", typeof child);\n }\n }\n\n return result;\n}\n\n/**\n * Check if a value is a VNode\n */\nexport function isVNode(value: unknown): value is VNode {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"type\" in value &&\n \"props\" in value &&\n \"children\" in value\n );\n}\n\n/**\n * Create a Fragment\n */\nexport function createFragment(children: JSXNode[]): VNode {\n return h(Fragment, null, ...children);\n}\n","/**\n * Unique symbol to mark Island components\n * This symbol is used to identify components that should be hydrated on the client\n */\nexport const ISLAND_MARKER: symbol = Symbol.for(\"semajsx.island\");\n","/**\n * Context API implementation\n */\n\nimport { h } from \"./vnode\";\nimport { Fragment } from \"./types\";\nimport type { ComponentAPI, Context as ContextType, ContextProps, VNode } from \"./types\";\n\n// Context map type - stores context values for current render environment\nexport type ContextMap = Map<symbol, any>;\n\n/**\n * Create a new Context (returns a typed Symbol)\n *\n * @param name - Optional name for debugging (defaults to \"anonymous\")\n * @returns Context symbol\n *\n * @example\n * ```typescript\n * const ThemeContext = context<Theme>();\n * const UserContext = context<User>('user'); // With debug name\n *\n * <Context provide={[ThemeContext, theme]}>\n * <App />\n * </Context>\n * ```\n */\nexport function context<T>(name?: string): ContextType<T> {\n const debugName = name || \"anonymous\";\n return Symbol(debugName) as ContextType<T>;\n}\n\n/**\n * Context component - provides context values to child components\n *\n * @example\n * ```typescript\n * // Single context\n * <Context provide={[ThemeContext, theme]}>\n * <App />\n * </Context>\n *\n * // Multiple contexts\n * <Context provide={[\n * [ThemeContext, theme],\n * [UserContext, user]\n * ]}>\n * <App />\n * </Context>\n * ```\n */\nexport function Context(props: ContextProps): VNode {\n const children = props.children\n ? Array.isArray(props.children)\n ? props.children\n : [props.children]\n : [];\n return h(Fragment, null, ...children);\n}\n\n// Mark as special context provider component\n(Context as any).__isContextProvider = true;\n\n/**\n * Create ComponentAPI instance for a component\n *\n * @param contextMap - The context map for current render environment\n * @returns ComponentAPI instance\n */\nexport function createComponentAPI(contextMap: ContextMap): ComponentAPI {\n return {\n inject<T>(context: ContextType<T>): T | undefined {\n return contextMap.get(context);\n },\n };\n}\n","import type { JSXNode } from \"./types\";\nimport type { Signal } from \"@semajsx/signal\";\nimport { computed, signal } from \"@semajsx/signal\";\n\n/**\n * Conditional rendering helper\n *\n * Renders content when condition signal is true, nothing when false.\n *\n * @example\n * // With VNode\n * const hint = when(showHint, <text>Press Ctrl+C to exit</text>);\n *\n * @example\n * // With function (lazy evaluation)\n * const hint = when(showHint, () => <text>Press Ctrl+C to exit</text>);\n */\nexport function when(\n condition: Signal<boolean>,\n content: JSXNode | (() => JSXNode),\n): Signal<JSXNode | null> {\n return computed([condition], (show) => {\n if (!show) return null;\n return typeof content === \"function\" ? content() : content;\n });\n}\n\n/**\n * Async resource helper for Promise<VNode>\n *\n * Renders pending content (or null) while the promise is pending, then renders\n * the resolved VNode. Handle errors in the promise itself using .catch().\n *\n * @example\n * // Handle everything in the promise\n * const content = resource(\n * fetchData()\n * .then(data => <text>{data}</text>)\n * .catch(err => <text color=\"red\">Error: {err.message}</text>)\n * );\n *\n * @example\n * // With optional pending content\n * const content = resource(\n * fetchData().then(data => <text>{data}</text>),\n * <text>Loading...</text>\n * );\n */\nexport function resource(promise: Promise<JSXNode>, pending?: JSXNode): Signal<JSXNode | null> {\n const content = signal<JSXNode | null>(pending || null);\n\n promise\n .then((result) => {\n content.value = result;\n })\n .catch((err) => {\n console.error(\"Unhandled promise rejection in resource():\", err);\n });\n\n return content;\n}\n\n/**\n * Async stream helper for AsyncIterable<VNode>\n *\n * Renders each yielded VNode from the async iterator, replacing the previous\n * content with each new value.\n *\n * @example\n * async function* generateContent() {\n * yield <text>Loading...</text>;\n * const data = await fetchData();\n * yield <text>Data: {data}</text>;\n * }\n *\n * const content = stream(generateContent());\n */\nexport function stream(\n iterator: AsyncIterable<JSXNode>,\n pending?: JSXNode,\n): Signal<JSXNode | null> {\n const content = signal<JSXNode | null>(pending || null);\n\n (async () => {\n try {\n for await (const vnode of iterator) {\n content.value = vnode;\n }\n } catch (err) {\n console.error(\"Error in stream():\", err);\n }\n })();\n\n return content;\n}\n","import { VNode, VNodeType } from \"./types\";\nimport { h } from \"./vnode\";\n\nexport function jsx(type: VNodeType, props: any, key?: any): VNode {\n const { children, ...restProps } = props || {};\n\n if (key !== undefined) {\n restProps.key = key;\n }\n\n if (children !== undefined) {\n return h(type, restProps, children);\n }\n\n return h(type, restProps);\n}\n\nexport function jsxs(type: VNodeType, props: any, key?: any): VNode {\n const { children, ...restProps } = props || {};\n\n if (key !== undefined) {\n restProps.key = key;\n }\n\n if (children !== undefined) {\n const childArray = Array.isArray(children) ? children : [children];\n return h(type, restProps, ...childArray);\n }\n\n return h(type, restProps);\n}\n","import type { JSXNode, JSXPrimitive, VNode } from \"./types\";\nimport { Fragment } from \"./types\";\nimport { isSignal } from \"@semajsx/signal\";\nimport { createSignalVNode, createTextVNode, isVNode } from \"./vnode\";\n\n/**\n * Normalize the `children` prop passed to components so it mirrors React semantics.\n * - 0 children => undefined\n * - 1 child => the child itself\n * - >1 children => array\n */\nexport function normalizeChildrenProp(children: VNode[]): VNode | VNode[] | undefined {\n if (children.length === 0) {\n return undefined;\n }\n if (children.length === 1) {\n return children[0];\n }\n return children;\n}\n\n/**\n * Normalize any JSXNode result from a component into a concrete VNode.\n */\nexport function normalizeComponentResult(result: VNode | JSXPrimitive | Iterable<JSXNode>): VNode {\n if (isVNode(result)) {\n return result;\n }\n\n if (typeof result === \"string\" || typeof result === \"number\") {\n return createTextVNode(result);\n }\n\n if (result == null || typeof result === \"boolean\") {\n return createTextVNode(\"\");\n }\n\n if (Array.isArray(result) || isIterable(result)) {\n const normalizedChildren = normalizeIterableChildren(result);\n return {\n type: Fragment,\n props: {},\n children: normalizedChildren,\n };\n }\n\n throw new Error(`Invalid component return type: ${typeof result}`);\n}\n\nfunction normalizeIterableChildren(children: Iterable<JSXNode>): VNode[] {\n const normalized: VNode[] = [];\n\n for (const child of children) {\n if (child == null || typeof child === \"boolean\") {\n continue;\n }\n\n if (Array.isArray(child) || isIterable(child)) {\n normalized.push(...normalizeIterableChildren(child as Iterable<JSXNode>));\n continue;\n }\n\n if (typeof child === \"string\" || typeof child === \"number\") {\n normalized.push(createTextVNode(child));\n continue;\n }\n\n if (isSignal(child)) {\n normalized.push(createSignalVNode(child));\n continue;\n }\n\n if (isVNode(child)) {\n normalized.push(child);\n continue;\n }\n\n throw new Error(`Invalid child in iterable: ${typeof child}`);\n }\n\n return normalized;\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return value != null && typeof (value as any)[Symbol.iterator] === \"function\";\n}\n","import type { VNode, Ref } from \"./types\";\nimport { Fragment, Portal } from \"./types\";\nimport { isSignal } from \"@semajsx/signal\";\nimport { isVNode } from \"./vnode\";\nimport { resource, stream } from \"./helpers\";\nimport { type ContextMap, createComponentAPI } from \"./context\";\nimport { normalizeChildrenProp, normalizeComponentResult } from \"./component\";\n\n/**\n * Generic rendered node structure\n */\nexport interface RenderedNode<TNode> {\n vnode: VNode;\n node: TNode | null;\n subscriptions: Array<() => void>;\n children: RenderedNode<TNode>[];\n}\n\n/**\n * Operations strategy for different rendering targets\n */\nexport interface RenderStrategy<TNode> {\n /**\n * Create a text node\n */\n createTextNode(text: string): TNode;\n\n /**\n * Create a comment node (used for markers)\n */\n createComment(text: string): TNode;\n\n /**\n * Create an element node\n */\n createElement(type: string): TNode;\n\n /**\n * Get the parent node of a node\n */\n getParent(node: TNode): TNode | null;\n\n /**\n * Get the next sibling of a node\n */\n getNextSibling(node: TNode): TNode | null;\n\n /**\n * Insert a node before another node\n */\n insertBefore(parent: TNode, newNode: TNode, beforeNode: TNode | null): void;\n\n /**\n * Append child to parent\n */\n appendChild(parent: TNode, child: TNode): void;\n\n /**\n * Remove child from its parent\n */\n removeChild(node: TNode): void;\n\n /**\n * Replace old node with new node\n */\n replaceNode(oldNode: TNode, newNode: TNode): void;\n\n /**\n * Set a property on a node\n */\n setProperty(node: TNode, key: string, value: unknown): void;\n\n /**\n * Set a signal property on a node (returns unsubscribe function)\n */\n setSignalProperty(node: TNode, key: string, signal: any): () => void;\n\n /**\n * Optional: Set a ref on a node (returns cleanup function)\n * This is only used for DOM rendering\n */\n setRef?(node: TNode, ref: Ref<TNode>): () => void;\n\n /**\n * Optional: Try to reuse an existing node instead of replacing it\n * Returns true if the node was successfully reused\n * This is used for DOM optimization but not needed for terminal\n */\n tryReuseNode?(\n oldNode: TNode,\n newNode: TNode,\n oldRendered: RenderedNode<TNode>,\n newRendered: RenderedNode<TNode>,\n ): boolean;\n}\n\n/**\n * Check if a value is a Promise\n */\nexport function isPromise<T>(value: any): value is Promise<T> {\n return value && typeof value.then === \"function\";\n}\n\n/**\n * Check if a value is an AsyncIterator\n */\nexport function isAsyncIterator<T>(value: any): value is AsyncIterableIterator<T> {\n return value && typeof value[Symbol.asyncIterator] === \"function\";\n}\n\n/**\n * Core rendering logic - works for both DOM and Terminal\n */\nexport function createRenderer<TNode>(strategy: RenderStrategy<TNode>): {\n renderNode: (vnode: VNode, parentContext: ContextMap) => RenderedNode<TNode>;\n unmount: (node: RenderedNode<TNode>) => void;\n cleanupSubscriptions: (node: RenderedNode<TNode>) => void;\n} {\n /**\n * Helper to recursively collect all actual DOM nodes from a rendered node\n * Handles fragments and signal nodes that may not have their own DOM node\n */\n function collectNodes(rendered: RenderedNode<TNode>): TNode[] {\n const nodes: TNode[] = [];\n\n // Fragment: no node, only children\n if (rendered.vnode.type === Fragment) {\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n return nodes;\n }\n\n // Portal: children are rendered into a different container,\n // so they should not be collected in the parent tree\n if (rendered.vnode.type === Portal) {\n return nodes;\n }\n\n // Signal marker: include marker node + content children\n if (rendered.vnode.type === \"#signal\") {\n if (rendered.node) {\n nodes.push(rendered.node); // marker\n }\n // Collect content children (after marker)\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n return nodes;\n }\n\n // Regular elements and text nodes: just the node itself\n // Children are already attached to the node\n if (rendered.node) {\n nodes.push(rendered.node);\n }\n\n return nodes;\n }\n\n /**\n * Render a single VNode\n */\n function renderNode(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const { type } = vnode;\n\n // Text node\n if (type === \"#text\") {\n return renderTextNode(vnode);\n }\n\n // Signal VNode\n if (type === \"#signal\") {\n return renderSignalNode(vnode, parentContext);\n }\n\n // Fragment\n if (type === Fragment) {\n return renderFragment(vnode, parentContext);\n }\n\n // Portal\n if (type === Portal) {\n return renderPortal(vnode, parentContext);\n }\n\n // Component\n if (typeof type === \"function\") {\n return renderComponent(vnode, parentContext);\n }\n\n // Element\n if (typeof type === \"string\") {\n return renderElement(vnode, parentContext);\n }\n\n throw new Error(`Unknown VNode type: ${String(type)}`);\n }\n\n /**\n * Render a text node\n */\n function renderTextNode(vnode: VNode): RenderedNode<TNode> {\n const text = vnode.props?.nodeValue || \"\";\n const node = strategy.createTextNode(text);\n\n return {\n vnode,\n node,\n subscriptions: [],\n children: [],\n };\n }\n\n /**\n * Render a signal VNode\n */\n function renderSignalNode(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const signal = vnode.props?.signal;\n // Use captured context if available (for async components), otherwise parent context\n const contextForSignal = vnode.props?.context || parentContext;\n\n if (!isSignal(signal)) {\n throw new Error(\"Signal VNode must have a signal prop\");\n }\n\n // Create a comment node as a marker to track the signal's position in the DOM\n // This is necessary because signal content might be a Fragment (no direct node)\n // or might be empty initially\n const marker = strategy.createComment(\"signal\");\n\n // Get initial value and render it\n const initialValue = signal.value;\n let currentRendered = renderValueToNode(initialValue, contextForSignal);\n\n const subscriptions: Array<() => void> = [];\n\n // Subscribe to signal changes\n const unsubscribe = signal.subscribe((value) => {\n const newRendered = renderValueToNode(value, contextForSignal);\n\n // Collect actual DOM nodes from old and new rendered trees\n const oldContentNodes = collectNodes(currentRendered);\n const newContentNodes = collectNodes(newRendered);\n\n // Get the parent from the marker\n const parent = strategy.getParent(marker);\n if (!parent) {\n console.warn(\"[Signal] Marker not in DOM, cannot update\");\n return;\n }\n\n // Remove all old content nodes\n for (const node of oldContentNodes) {\n strategy.removeChild(node);\n }\n\n // Insert new content nodes after the marker\n let insertAfter = strategy.getNextSibling(marker);\n for (const node of newContentNodes) {\n strategy.insertBefore(parent, node, insertAfter);\n // Update insertAfter to maintain order (insert at the position after the last inserted)\n insertAfter = strategy.getNextSibling(node);\n }\n\n // Unmount old rendered tree: cleans up subscriptions AND removes\n // portal children from their containers (cleanupSubscriptions alone\n // would leave portal content orphaned in the portal container)\n unmount(currentRendered);\n\n currentRendered = newRendered;\n });\n\n subscriptions.push(unsubscribe);\n\n return {\n vnode,\n node: marker,\n subscriptions,\n children: currentRendered ? [currentRendered] : [],\n };\n }\n\n /**\n * Helper to convert a signal value to a rendered node\n */\n function renderValueToNode(value: unknown, context: ContextMap): RenderedNode<TNode> {\n let newVNode: VNode;\n\n // Convert value to VNode\n if (isVNode(value)) {\n newVNode = value;\n } else if (Array.isArray(value)) {\n // Support arrays - wrap in Fragment automatically\n // This allows: computed(todos, list => list.map(...))\n // Without requiring manual Fragment wrapping\n newVNode = {\n type: Fragment,\n props: {},\n children: value.filter(isVNode), // Filter out non-VNodes\n };\n } else if (typeof value === \"string\" || typeof value === \"number\") {\n newVNode = {\n type: \"#text\",\n props: { nodeValue: String(value) },\n children: [],\n };\n } else if (value == null || typeof value === \"boolean\") {\n // Render empty text for null/undefined/boolean\n // This works for both DOM and terminal\n newVNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n } else {\n throw new Error(`Invalid signal value type: ${typeof value}`);\n }\n\n return renderNode(newVNode, context);\n }\n\n /**\n * Render a fragment\n */\n function renderFragment(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const children = vnode.children.map((child) => renderNode(child, parentContext));\n\n // Fragment has no node of its own\n return {\n vnode,\n node: null,\n subscriptions: [],\n children,\n };\n }\n\n /**\n * Render a portal\n * Portal renders its children into a different container\n */\n function renderPortal(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const container = vnode.props?.container;\n\n if (!container) {\n throw new Error(\"Portal must have a container prop\");\n }\n\n // Render children with same context\n const children = vnode.children.map((child) => renderNode(child, parentContext));\n\n // Append all child nodes to the portal container (recursively handles fragments)\n for (const child of children) {\n const nodes = collectNodes(child);\n for (const node of nodes) {\n strategy.appendChild(container, node);\n }\n }\n\n // Portal has no node in the parent tree\n return {\n vnode,\n node: null,\n subscriptions: [],\n children,\n };\n }\n\n /**\n * Render a component\n */\n function renderComponent(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n if (typeof vnode.type !== \"function\") {\n throw new Error(\"Component vnode must have a function type\");\n }\n\n const Component = vnode.type;\n const props = {\n ...vnode.props,\n children: normalizeChildrenProp(vnode.children),\n };\n\n // Prepare current component's context\n let currentContext = parentContext;\n\n // Check if this is a Context Provider\n const isContextProvider = (Component as any).__isContextProvider;\n\n if (isContextProvider) {\n // Context Provider: create new context map with provided values\n currentContext = new Map(parentContext);\n const provide = (props as any).provide;\n\n if (provide) {\n // Check if it's a single provide [Context, value] or multiple [[Context, value], ...]\n const isSingle = provide.length === 2 && typeof provide[0] === \"symbol\";\n\n if (isSingle) {\n // Single: [Context, value]\n const [context, value] = provide;\n currentContext.set(context, value);\n } else {\n // Multiple: [[Context, value], ...]\n for (const [context, value] of provide) {\n currentContext.set(context, value);\n }\n }\n }\n }\n\n // Create ComponentAPI\n const ctx = createComponentAPI(currentContext);\n\n // Call component function with props and ctx\n const result = Component(props, ctx);\n\n // Handle async component (Promise<VNode>)\n if (isPromise(result)) {\n const pending: VNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n const resultSignal = resource(result, pending);\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: resultSignal, context: currentContext },\n children: [],\n };\n const rendered = renderNode(signalVNode, currentContext);\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n // Handle async generator component (AsyncIterableIterator<VNode>)\n if (isAsyncIterator(result)) {\n const pending: VNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n const resultSignal = stream(result, pending);\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: resultSignal, context: currentContext },\n children: [],\n };\n const rendered = renderNode(signalVNode, currentContext);\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n // Handle signal component (Signal<VNode>)\n if (isSignal(result)) {\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: result, context: currentContext },\n children: [],\n };\n const rendered = renderNode(signalVNode, currentContext);\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n // Handle normal sync component (VNode)\n const normalizedResult = normalizeComponentResult(result);\n const rendered = renderNode(normalizedResult, currentContext);\n\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n /**\n * Render an element\n */\n function renderElement(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n if (typeof vnode.type !== \"string\") {\n throw new Error(\"Element vnode must have a string type\");\n }\n\n const element = strategy.createElement(vnode.type);\n const subscriptions: Array<() => void> = [];\n\n // Apply props\n const props = vnode.props || {};\n for (const [key, value] of Object.entries(props)) {\n if (key === \"key\" || key === \"children\") continue;\n\n // Handle ref separately\n if (key === \"ref\") {\n if (strategy.setRef && value != null) {\n const cleanup = strategy.setRef(element, value as Ref<TNode>);\n subscriptions.push(cleanup);\n }\n continue;\n }\n\n if (isSignal(value)) {\n const unsub = strategy.setSignalProperty(element, key, value);\n subscriptions.push(unsub);\n } else {\n strategy.setProperty(element, key, value);\n }\n }\n\n // Render children with same context\n const children = vnode.children.map((child) => renderNode(child, parentContext));\n\n // Append all child nodes (recursively handles fragments and signal wrappers)\n for (const child of children) {\n const nodes = collectNodes(child);\n for (const node of nodes) {\n strategy.appendChild(element, node);\n }\n }\n\n return {\n vnode,\n node: element,\n subscriptions,\n children,\n };\n }\n\n /**\n * Unmount a rendered node\n */\n function unmount(node: RenderedNode<TNode>): void {\n // Cleanup subscriptions\n for (const unsub of node.subscriptions) {\n unsub();\n }\n\n // Recursively unmount children\n for (const child of node.children) {\n unmount(child);\n }\n\n // Remove from tree\n if (node.node) {\n strategy.removeChild(node.node);\n }\n }\n\n /**\n * Clean up subscriptions without removing nodes from tree\n */\n function cleanupSubscriptions(node: RenderedNode<TNode>): void {\n // Cleanup subscriptions\n for (const unsub of node.subscriptions) {\n unsub();\n }\n\n // Recursively cleanup children\n for (const child of node.children) {\n cleanupSubscriptions(child);\n }\n }\n\n return {\n renderNode: renderNode,\n unmount: unmount,\n cleanupSubscriptions: cleanupSubscriptions,\n };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-CRi0xsNK.mjs","names":[],"sources":["../../dom/src/operations.ts","../../dom/src/properties.ts","../../dom/src/render.ts","../../dom/src/portal.ts","../../dom/src/style-anchor.ts"],"sourcesContent":["/**\n * Low-level DOM operations\n */\n\nexport function createElement(tagName: string): Element {\n return document.createElement(tagName);\n}\n\nexport function createTextNode(text: string): Text {\n return document.createTextNode(text);\n}\n\nexport function createComment(text: string): Comment {\n return document.createComment(text);\n}\n\nexport function appendChild(parent: Node, child: Node): void {\n parent.appendChild(child);\n}\n\nexport function removeChild(node: Node): void {\n node.parentNode?.removeChild(node);\n}\n\nexport function insertBefore(parent: Node, newNode: Node, refNode: Node | null): void {\n parent.insertBefore(newNode, refNode);\n}\n\nexport function replaceNode(oldNode: Node, newNode: Node): void {\n oldNode.parentNode?.replaceChild(newNode, oldNode);\n}\n\nexport function setText(node: Node, text: string): void {\n node.textContent = text;\n}\n\nexport function getParent(node: Node): Node | null {\n return node.parentNode;\n}\n\nexport function getNextSibling(node: Node): Node | null {\n return node.nextSibling;\n}\n","import type { Signal } from \"@semajsx/signal\";\nimport type { Ref } from \"@semajsx/core\";\nimport { isSignal } from \"@semajsx/signal\";\nimport { isStyleToken, inject, type StyleToken } from \"@semajsx/style\";\n\n/**\n * Class value type - can be string, StyleToken, array, or falsy\n */\ntype ClassValue = string | StyleToken | ClassValue[] | false | null | undefined;\n\n/**\n * Resolve a class value to a string\n *\n * Supports:\n * - Strings: returned as-is\n * - StyleTokens: injects CSS and returns className\n * - Arrays: recursively resolves all values\n * - Falsy values: filtered out\n *\n * @example\n * resolveClass(\"btn\") // \"btn\"\n * resolveClass(button.root) // \"root-x7f3a\" (injects CSS)\n * resolveClass([button.root, \"custom\", isLarge && button.large]) // \"root-x7f3a custom large-y8g4b\"\n */\nfunction resolveClass(value: ClassValue): string {\n if (!value) {\n return \"\";\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (isStyleToken(value)) {\n // Inject CSS for the token\n inject(value);\n // Return the className (or empty string if none)\n return value._ ?? \"\";\n }\n\n if (Array.isArray(value)) {\n // Recursively resolve array values, filter empty strings\n return value.map(resolveClass).filter(Boolean).join(\" \");\n }\n\n return \"\";\n}\n\n/**\n * Set a property on an element\n */\nexport function setProperty(element: Element, key: string, value: unknown): void {\n // Skip internal props\n if (key === \"key\" || key === \"ref\" || key === \"children\") {\n return;\n }\n\n // Handle events\n if (key.startsWith(\"on\") && typeof value === \"function\") {\n const eventName = key.toLowerCase().substring(2); // \"onClick\" -> \"click\"\n\n // Use addEventListener instead of property assignment for better reliability\n // especially in hydration scenarios\n const element_any = element as any;\n\n // Remove old listener if exists (stored on element)\n const oldListener = element_any[`__${key}`];\n if (oldListener) {\n element.removeEventListener(eventName, oldListener);\n }\n\n // Add new listener and store reference for future cleanup\n element.addEventListener(eventName, value as EventListener);\n element_any[`__${key}`] = value;\n\n return;\n }\n\n // Handle className/class with StyleToken support\n if (key === \"className\" || key === \"class\") {\n if (value == null) {\n element.removeAttribute(\"class\");\n return;\n }\n\n // Resolve class value (may be string, StyleToken, or array)\n const resolvedClass = resolveClass(value as ClassValue);\n if (resolvedClass) {\n element.setAttribute(\"class\", resolvedClass);\n } else {\n element.removeAttribute(\"class\");\n }\n return;\n }\n\n // Handle style\n if (key === \"style\" && element instanceof HTMLElement) {\n if (typeof value === \"string\") {\n element.style.cssText = value;\n } else if (typeof value === \"object\" && value !== null) {\n Object.assign(element.style, value);\n }\n return;\n }\n\n // Handle special boolean attributes\n if (typeof value === \"boolean\") {\n if (value) {\n element.setAttribute(key, \"\");\n } else {\n element.removeAttribute(key);\n }\n return;\n }\n\n // Handle value for form elements\n if (key === \"value\") {\n if (\n element instanceof HTMLInputElement ||\n element instanceof HTMLTextAreaElement ||\n element instanceof HTMLSelectElement\n ) {\n element.value = String(value ?? \"\");\n return;\n }\n }\n\n // Handle checked for checkboxes\n if (key === \"checked\" && element instanceof HTMLInputElement) {\n element.checked = Boolean(value);\n return;\n }\n\n // Default: set as attribute\n if (value == null) {\n element.removeAttribute(key);\n } else {\n element.setAttribute(key, String(value));\n }\n}\n\n/**\n * Set a signal property on an element\n */\nexport function setSignalProperty<T = unknown>(\n element: Element,\n key: string,\n signal: Signal<T>,\n): () => void {\n // Set initial value\n setProperty(element, key, signal.value);\n\n // Subscribe to changes and update property\n return signal.subscribe((value: T) => {\n setProperty(element, key, value);\n });\n}\n\n/**\n * Set a ref on an element\n * - Supports both Signal refs and callback refs\n * - Returns a cleanup function to clear the ref\n */\nexport function setRef(element: Node, ref: Ref<any>): () => void {\n // Signal ref\n if (isSignal(ref)) {\n ref.value = element;\n return () => {\n ref.value = null;\n };\n }\n\n // Callback ref\n if (typeof ref === \"function\") {\n ref(element);\n return () => {\n ref(null);\n };\n }\n\n // Invalid ref type\n return () => {};\n}\n","import type { VNode } from \"@semajsx/core\";\nimport {\n resource,\n stream,\n createRenderer,\n isAsyncIterator,\n isPromise,\n Fragment,\n Portal,\n type RenderedNode,\n type RenderStrategy,\n type ContextMap,\n} from \"@semajsx/core\";\nimport { setProperty, setSignalProperty, setRef } from \"./properties\";\nimport {\n appendChild,\n createElement,\n createTextNode,\n createComment,\n removeChild,\n replaceNode,\n insertBefore,\n getParent,\n getNextSibling,\n} from \"./operations\";\n\n/**\n * Helper to recursively collect all actual DOM nodes from a rendered node\n * Handles fragments and signal nodes that may not have their own DOM node\n */\nfunction collectNodes(rendered: RenderedNode<Node>): Node[] {\n const nodes: Node[] = [];\n\n // Portal: children are already rendered to the portal container\n // Don't collect them here as they shouldn't be added to the main tree\n if (rendered.vnode.type === Portal) {\n return nodes;\n }\n\n // Fragment: no node, only children\n if (rendered.vnode.type === Fragment) {\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n return nodes;\n }\n\n // Signal marker: include marker node + content children\n if (rendered.vnode.type === \"#signal\") {\n if (rendered.node) {\n nodes.push(rendered.node); // marker\n }\n // Collect content children (after marker)\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n return nodes;\n }\n\n // Regular elements and text nodes: just the node itself\n if (rendered.node) {\n nodes.push(rendered.node);\n } else if (rendered.children.length > 0) {\n // Component returned Fragment or other node-less structure\n // Need to collect from children\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n }\n return nodes;\n}\n\n/**\n * Result returned by the render function\n */\nexport interface DOMRenderResult {\n /**\n * Unmount the rendered tree and cleanup subscriptions\n */\n unmount: () => void;\n}\n\n/**\n * DOM-specific render strategy with optimization\n */\nconst domStrategy: RenderStrategy<Node> = {\n createTextNode,\n createComment,\n createElement,\n getParent,\n getNextSibling,\n insertBefore,\n appendChild,\n removeChild,\n replaceNode,\n setProperty,\n setSignalProperty,\n setRef,\n tryReuseNode,\n};\n\n// Create DOM renderer with optimization\nconst { renderNode, unmount: unmountCore } = createRenderer(domStrategy);\n\n/**\n * Render a VNode tree to the DOM\n * Supports sync VNodes, async VNodes (Promise), and streaming VNodes (AsyncIterableIterator)\n *\n * @example\n * // Basic usage\n * const { unmount } = render(<App />, container);\n *\n * @example\n * // With signals (auto-updates)\n * const count = signal(0);\n * render(<div>{count}</div>, container);\n * count.value++; // UI updates automatically\n *\n * @example\n * // Cleanup when needed\n * const { unmount } = render(<App />, container);\n * unmount();\n */\nexport function render(\n element: VNode | Promise<VNode> | AsyncIterableIterator<VNode>,\n container: Element,\n): DOMRenderResult {\n // Initialize empty context map for root render\n const initialContext: ContextMap = new Map();\n\n let rendered: RenderedNode<Node>;\n\n // Handle async element (Promise<VNode>)\n if (isPromise(element)) {\n const pending: VNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n const resultSignal = resource(element, pending);\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: resultSignal, context: initialContext },\n children: [],\n };\n rendered = renderNode(signalVNode, initialContext);\n if (rendered.node) {\n appendChild(container, rendered.node);\n }\n } else if (isAsyncIterator(element)) {\n // Handle async generator (AsyncIterableIterator<VNode>)\n const pending: VNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n const resultSignal = stream(element, pending);\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: resultSignal, context: initialContext },\n children: [],\n };\n rendered = renderNode(signalVNode, initialContext);\n if (rendered.node) {\n appendChild(container, rendered.node);\n }\n } else {\n // Handle sync VNode\n rendered = renderNode(element, initialContext);\n\n // Collect all nodes (handles Fragments with multiple children)\n const nodes = collectNodes(rendered);\n for (const node of nodes) {\n appendChild(container, node);\n }\n }\n\n // Return result object with unmount method\n return {\n unmount: () => unmountCore(rendered),\n };\n}\n\n/**\n * Try to reuse an existing DOM node instead of replacing it\n * Returns true if the node was successfully reused\n */\nfunction tryReuseNode(\n oldDom: Node,\n newDom: Node,\n oldRendered: RenderedNode<Node>,\n newRendered: RenderedNode<Node>,\n): boolean {\n // Both are text nodes - just update the content\n if (oldDom.nodeType === Node.TEXT_NODE && newDom.nodeType === Node.TEXT_NODE) {\n if (oldDom.textContent !== newDom.textContent) {\n oldDom.textContent = newDom.textContent;\n }\n // Update the newRendered to point to the old (reused) DOM node\n newRendered.node = oldDom;\n return true;\n }\n\n // Both are elements with the same tag name - update properties and children\n if (\n oldDom.nodeType === Node.ELEMENT_NODE &&\n newDom.nodeType === Node.ELEMENT_NODE &&\n (oldDom as Element).tagName === (newDom as Element).tagName\n ) {\n const oldElement = oldDom as Element;\n const newElement = newDom as Element;\n\n // Update attributes\n // Remove old attributes\n for (let i = oldElement.attributes.length - 1; i >= 0; i--) {\n const attr = oldElement.attributes[i];\n if (attr && !newElement.hasAttribute(attr.name)) {\n oldElement.removeAttribute(attr.name);\n }\n }\n\n // Set new attributes\n for (let i = 0; i < newElement.attributes.length; i++) {\n const attr = newElement.attributes[i];\n if (attr && oldElement.getAttribute(attr.name) !== attr.value) {\n oldElement.setAttribute(attr.name, attr.value);\n }\n }\n\n // Use keyed reconciliation if children have keys\n const hasKeys = hasChildKeys(oldRendered) || hasChildKeys(newRendered);\n\n if (hasKeys && oldRendered.children.length > 0 && newRendered.children.length > 0) {\n reconcileKeyedChildren(oldElement, oldRendered.children, newRendered.children);\n } else {\n // Fallback: replace all children\n // Clear old children\n while (oldElement.firstChild) {\n oldElement.removeChild(oldElement.firstChild);\n }\n\n // Add new children\n while (newElement.firstChild) {\n oldElement.appendChild(newElement.firstChild);\n }\n }\n\n // Update the newRendered to point to the old (reused) DOM node\n newRendered.node = oldDom;\n\n // Cleanup old subscriptions\n for (const unsub of oldRendered.subscriptions) {\n unsub();\n }\n\n return true;\n }\n\n // Different node types - can't reuse\n return false;\n}\n\n/**\n * Check if any children have keys\n */\nfunction hasChildKeys(rendered: RenderedNode<Node>): boolean {\n return rendered.children.some((child) => child.vnode.key != null);\n}\n\n/**\n * Reconcile children using keys for efficient list updates\n */\nfunction reconcileKeyedChildren(\n parent: Element,\n oldChildren: RenderedNode<Node>[],\n newChildren: RenderedNode<Node>[],\n): void {\n // Build a map of old children by key\n const oldKeyMap = new Map<string | number, RenderedNode<Node>>();\n const oldKeylessChildren: RenderedNode<Node>[] = [];\n\n for (const child of oldChildren) {\n if (child.vnode.key != null) {\n oldKeyMap.set(child.vnode.key, child);\n } else {\n oldKeylessChildren.push(child);\n }\n }\n\n // Track which old children have been reused\n const reusedKeys = new Set<string | number>();\n let keylessIndex = 0;\n\n // Process new children\n for (let i = 0; i < newChildren.length; i++) {\n const newChild = newChildren[i];\n if (!newChild) continue;\n\n const newKey = newChild.vnode.key;\n let oldChild: RenderedNode<Node> | undefined;\n let reused = false;\n\n // Try to find matching old child by key\n if (newKey != null) {\n oldChild = oldKeyMap.get(newKey);\n if (oldChild) {\n reusedKeys.add(newKey);\n reused = true;\n }\n } else {\n // No key, try to reuse next keyless child\n if (keylessIndex < oldKeylessChildren.length) {\n oldChild = oldKeylessChildren[keylessIndex++];\n }\n }\n\n // If we found a matching old child, try to update it\n if (oldChild && reused && oldChild.node && newChild.node) {\n const sameType =\n oldChild.vnode.type === newChild.vnode.type ||\n (oldChild.node.nodeType === Node.TEXT_NODE && newChild.node.nodeType === Node.TEXT_NODE);\n\n if (sameType) {\n // Try to reuse the node\n const nodeReused = tryReuseNode(oldChild.node, newChild.node, oldChild, newChild);\n\n if (nodeReused) {\n // Ensure the child is in the correct position\n const currentNode = parent.childNodes[i];\n if (currentNode !== oldChild.node) {\n parent.insertBefore(oldChild.node, currentNode || null);\n }\n continue;\n }\n }\n }\n\n // Can't reuse, insert the new child\n if (newChild.node) {\n const currentNode = parent.childNodes[i];\n if (currentNode) {\n parent.insertBefore(newChild.node, currentNode);\n } else {\n parent.appendChild(newChild.node);\n }\n }\n }\n\n // Remove old children that weren't reused\n for (const [key, oldChild] of oldKeyMap) {\n if (!reusedKeys.has(key) && oldChild.node) {\n removeChild(oldChild.node);\n unmountCore(oldChild);\n }\n }\n\n // Remove excess keyless children\n for (let i = keylessIndex; i < oldKeylessChildren.length; i++) {\n const oldChild = oldKeylessChildren[i];\n if (oldChild && oldChild.node) {\n removeChild(oldChild.node);\n unmountCore(oldChild);\n }\n }\n\n // Remove any extra DOM nodes that are still in the parent\n while (parent.childNodes.length > newChildren.length) {\n const lastChild = parent.lastChild;\n if (lastChild) {\n parent.removeChild(lastChild);\n }\n }\n}\n","import type { JSXNode, VNode } from \"@semajsx/core\";\nimport { Portal, h } from \"@semajsx/core\";\n\n/**\n * Portal props interface\n */\nexport interface PortalProps {\n children: JSXNode;\n container: Element;\n}\n\n/**\n * Create a portal VNode that renders children into a different DOM container\n *\n * @param children - The children to render\n * @param container - The target DOM container element\n * @returns A portal VNode\n *\n * @example\n * ```tsx\n * const Modal = () => {\n * return createPortal(\n * <div class=\"modal\">Modal content</div>,\n * document.body\n * );\n * };\n * ```\n */\nexport function createPortal(children: JSXNode, container: Element): VNode {\n // Use h() to create Portal VNode with proper normalization\n return h(Portal, { container }, children);\n}\n\n/**\n * Portal component (alternative to createPortal function)\n *\n * @example\n * ```tsx\n * <Portal container={document.body}>\n * <div class=\"modal\">Modal content</div>\n * </Portal>\n * ```\n */\nexport function PortalComponent(props: PortalProps): VNode {\n return createPortal(props.children, props.container);\n}\n","/**\n * Style anchor components for @semajsx/dom\n *\n * These components control where styles are injected in the DOM.\n * Useful for Shadow DOM and component-scoped style injection.\n */\n\nimport type { VNode, JSXNode } from \"@semajsx/core\";\nimport { Fragment } from \"@semajsx/core\";\n\n/**\n * Style anchor context - stores the current injection target\n */\nlet appStyleTarget: Element | ShadowRoot | null = null;\nlet componentStyleTarget: Element | ShadowRoot | null = null;\n\n/**\n * Get the current style injection target\n *\n * Priority:\n * 1. Component anchor (if set)\n * 2. App anchor (if set)\n * 3. document.head (default)\n */\nexport function getStyleTarget(): Element | ShadowRoot {\n return componentStyleTarget ?? appStyleTarget ?? document.head;\n}\n\n/**\n * Set the app-level style injection target\n *\n * Use this for Shadow DOM to inject styles into the shadow root\n * instead of document.head.\n */\nexport function setAppStyleTarget(target: Element | ShadowRoot | null): void {\n appStyleTarget = target;\n}\n\n/**\n * Set the component-level style injection target\n *\n * This only affects the current component, not children.\n */\nexport function setComponentStyleTarget(target: Element | ShadowRoot | null): void {\n componentStyleTarget = target;\n}\n\n/**\n * AppStyleAnchor props\n */\nexport interface AppStyleAnchorProps {\n /** The target element or shadow root for style injection */\n target: Element | ShadowRoot;\n /** Children to render */\n children?: JSXNode;\n}\n\n/**\n * AppStyleAnchor - Sets the global style injection target\n *\n * Use this component to redirect all style injection to a specific target,\n * typically a Shadow DOM root.\n *\n * @example\n * ```tsx\n * function MyWebComponent() {\n * const shadow = useShadowRoot();\n *\n * return (\n * <AppStyleAnchor target={shadow}>\n * <App />\n * </AppStyleAnchor>\n * );\n * }\n * ```\n */\nexport function AppStyleAnchor({ target, children }: AppStyleAnchorProps): VNode {\n // Set the target when the component mounts\n setAppStyleTarget(target);\n\n // Return children wrapped in a fragment\n return {\n type: Fragment,\n props: {},\n children: children ? [children as VNode] : [],\n key: undefined,\n };\n}\n\n/**\n * ComponentStyleAnchor props\n */\nexport interface ComponentStyleAnchorProps {\n /** The target element or shadow root for style injection */\n target: Element | ShadowRoot;\n /** Children to render */\n children?: JSXNode;\n}\n\n/**\n * ComponentStyleAnchor - Sets style injection target for current component only\n *\n * Unlike AppStyleAnchor, this only affects styles used directly in the\n * component where it's declared. Child components use the App anchor\n * or fall back to document.head.\n *\n * @example\n * ```tsx\n * function IsolatedComponent() {\n * const containerRef = signal<HTMLElement | null>(null);\n *\n * return (\n * <div>\n * <style-container ref={containerRef} />\n * <ComponentStyleAnchor target={containerRef}>\n * <div class={card.root}>...</div>\n * <ChildComponent /> {* Uses App anchor, NOT this anchor *}\n * </ComponentStyleAnchor>\n * </div>\n * );\n * }\n * ```\n */\nexport function ComponentStyleAnchor({ target, children }: ComponentStyleAnchorProps): VNode {\n // Set the target when the component mounts\n setComponentStyleTarget(target);\n\n // Return children wrapped in a fragment\n return {\n type: Fragment,\n props: {},\n children: children ? [children as VNode] : [],\n key: undefined,\n };\n}\n"],"mappings":"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"}