@typed/template 0.1.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 (285) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/cjs/Directive.js +76 -0
  4. package/dist/cjs/Directive.js.map +1 -0
  5. package/dist/cjs/ElementRef.js +83 -0
  6. package/dist/cjs/ElementRef.js.map +1 -0
  7. package/dist/cjs/ElementSource.js +244 -0
  8. package/dist/cjs/ElementSource.js.map +1 -0
  9. package/dist/cjs/Entry.js +6 -0
  10. package/dist/cjs/Entry.js.map +1 -0
  11. package/dist/cjs/EventHandler.js +65 -0
  12. package/dist/cjs/EventHandler.js.map +1 -0
  13. package/dist/cjs/Html.js +169 -0
  14. package/dist/cjs/Html.js.map +1 -0
  15. package/dist/cjs/HtmlChunk.js +257 -0
  16. package/dist/cjs/HtmlChunk.js.map +1 -0
  17. package/dist/cjs/Hydrate.js +49 -0
  18. package/dist/cjs/Hydrate.js.map +1 -0
  19. package/dist/cjs/Many.js +45 -0
  20. package/dist/cjs/Many.js.map +1 -0
  21. package/dist/cjs/Meta.js +37 -0
  22. package/dist/cjs/Meta.js.map +1 -0
  23. package/dist/cjs/Parser.js +331 -0
  24. package/dist/cjs/Parser.js.map +1 -0
  25. package/dist/cjs/Part.js +6 -0
  26. package/dist/cjs/Part.js.map +1 -0
  27. package/dist/cjs/Placeholder.js +38 -0
  28. package/dist/cjs/Placeholder.js.map +1 -0
  29. package/dist/cjs/Platform.js +64 -0
  30. package/dist/cjs/Platform.js.map +1 -0
  31. package/dist/cjs/Render.js +39 -0
  32. package/dist/cjs/Render.js.map +1 -0
  33. package/dist/cjs/RenderContext.js +130 -0
  34. package/dist/cjs/RenderContext.js.map +1 -0
  35. package/dist/cjs/RenderEvent.js +44 -0
  36. package/dist/cjs/RenderEvent.js.map +1 -0
  37. package/dist/cjs/RenderTemplate.js +41 -0
  38. package/dist/cjs/RenderTemplate.js.map +1 -0
  39. package/dist/cjs/Renderable.js +6 -0
  40. package/dist/cjs/Renderable.js.map +1 -0
  41. package/dist/cjs/Template.js +266 -0
  42. package/dist/cjs/Template.js.map +1 -0
  43. package/dist/cjs/TemplateInstance.js +51 -0
  44. package/dist/cjs/TemplateInstance.js.map +1 -0
  45. package/dist/cjs/Test.js +90 -0
  46. package/dist/cjs/Test.js.map +1 -0
  47. package/dist/cjs/Token.js +270 -0
  48. package/dist/cjs/Token.js.map +1 -0
  49. package/dist/cjs/Tokenizer.js +18 -0
  50. package/dist/cjs/Tokenizer.js.map +1 -0
  51. package/dist/cjs/Vitest.js +44 -0
  52. package/dist/cjs/Vitest.js.map +1 -0
  53. package/dist/cjs/index.js +147 -0
  54. package/dist/cjs/index.js.map +1 -0
  55. package/dist/cjs/internal/HydrateContext.js +13 -0
  56. package/dist/cjs/internal/HydrateContext.js.map +1 -0
  57. package/dist/cjs/internal/browser.js +109 -0
  58. package/dist/cjs/internal/browser.js.map +1 -0
  59. package/dist/cjs/internal/chunks.js +54 -0
  60. package/dist/cjs/internal/chunks.js.map +1 -0
  61. package/dist/cjs/internal/errors.js +23 -0
  62. package/dist/cjs/internal/errors.js.map +1 -0
  63. package/dist/cjs/internal/hydrate.js +197 -0
  64. package/dist/cjs/internal/hydrate.js.map +1 -0
  65. package/dist/cjs/internal/indexRefCounter.js +32 -0
  66. package/dist/cjs/internal/indexRefCounter.js.map +1 -0
  67. package/dist/cjs/internal/module-augmentation.js +6 -0
  68. package/dist/cjs/internal/module-augmentation.js.map +1 -0
  69. package/dist/cjs/internal/parser.js +492 -0
  70. package/dist/cjs/internal/parser.js.map +1 -0
  71. package/dist/cjs/internal/parts.js +350 -0
  72. package/dist/cjs/internal/parts.js.map +1 -0
  73. package/dist/cjs/internal/readAttribute.js +34 -0
  74. package/dist/cjs/internal/readAttribute.js.map +1 -0
  75. package/dist/cjs/internal/render.js +332 -0
  76. package/dist/cjs/internal/render.js.map +1 -0
  77. package/dist/cjs/internal/server.js +219 -0
  78. package/dist/cjs/internal/server.js.map +1 -0
  79. package/dist/cjs/internal/tokenizer.js +264 -0
  80. package/dist/cjs/internal/tokenizer.js.map +1 -0
  81. package/dist/cjs/internal/utils.js +68 -0
  82. package/dist/cjs/internal/utils.js.map +1 -0
  83. package/dist/dts/Directive.d.ts +70 -0
  84. package/dist/dts/Directive.d.ts.map +1 -0
  85. package/dist/dts/ElementRef.d.ts +40 -0
  86. package/dist/dts/ElementRef.d.ts.map +1 -0
  87. package/dist/dts/ElementSource.d.ts +72 -0
  88. package/dist/dts/ElementSource.d.ts.map +1 -0
  89. package/dist/dts/Entry.d.ts +26 -0
  90. package/dist/dts/Entry.d.ts.map +1 -0
  91. package/dist/dts/EventHandler.d.ts +61 -0
  92. package/dist/dts/EventHandler.d.ts.map +1 -0
  93. package/dist/dts/Html.d.ts +17 -0
  94. package/dist/dts/Html.d.ts.map +1 -0
  95. package/dist/dts/HtmlChunk.d.ts +56 -0
  96. package/dist/dts/HtmlChunk.d.ts.map +1 -0
  97. package/dist/dts/Hydrate.d.ts +20 -0
  98. package/dist/dts/Hydrate.d.ts.map +1 -0
  99. package/dist/dts/Many.d.ts +32 -0
  100. package/dist/dts/Many.d.ts.map +1 -0
  101. package/dist/dts/Meta.d.ts +24 -0
  102. package/dist/dts/Meta.d.ts.map +1 -0
  103. package/dist/dts/Parser.d.ts +16 -0
  104. package/dist/dts/Parser.d.ts.map +1 -0
  105. package/dist/dts/Part.d.ts +147 -0
  106. package/dist/dts/Part.d.ts.map +1 -0
  107. package/dist/dts/Placeholder.d.ts +51 -0
  108. package/dist/dts/Placeholder.d.ts.map +1 -0
  109. package/dist/dts/Platform.d.ts +23 -0
  110. package/dist/dts/Platform.d.ts.map +1 -0
  111. package/dist/dts/Render.d.ts +23 -0
  112. package/dist/dts/Render.d.ts.map +1 -0
  113. package/dist/dts/RenderContext.d.ts +88 -0
  114. package/dist/dts/RenderContext.d.ts.map +1 -0
  115. package/dist/dts/RenderEvent.d.ts +37 -0
  116. package/dist/dts/RenderEvent.d.ts.map +1 -0
  117. package/dist/dts/RenderTemplate.d.ts +38 -0
  118. package/dist/dts/RenderTemplate.d.ts.map +1 -0
  119. package/dist/dts/Renderable.d.ts +28 -0
  120. package/dist/dts/Renderable.d.ts.map +1 -0
  121. package/dist/dts/Template.d.ts +218 -0
  122. package/dist/dts/Template.d.ts.map +1 -0
  123. package/dist/dts/TemplateInstance.d.ts +32 -0
  124. package/dist/dts/TemplateInstance.d.ts.map +1 -0
  125. package/dist/dts/Test.d.ts +58 -0
  126. package/dist/dts/Test.d.ts.map +1 -0
  127. package/dist/dts/Token.d.ts +202 -0
  128. package/dist/dts/Token.d.ts.map +1 -0
  129. package/dist/dts/Tokenizer.d.ts +6 -0
  130. package/dist/dts/Tokenizer.d.ts.map +1 -0
  131. package/dist/dts/Vitest.d.ts +28 -0
  132. package/dist/dts/Vitest.d.ts.map +1 -0
  133. package/dist/dts/index.d.ts +65 -0
  134. package/dist/dts/index.d.ts.map +1 -0
  135. package/dist/dts/internal/HydrateContext.d.ts +2 -0
  136. package/dist/dts/internal/HydrateContext.d.ts.map +1 -0
  137. package/dist/dts/internal/browser.d.ts +8 -0
  138. package/dist/dts/internal/browser.d.ts.map +1 -0
  139. package/dist/dts/internal/chunks.d.ts +22 -0
  140. package/dist/dts/internal/chunks.d.ts.map +1 -0
  141. package/dist/dts/internal/errors.d.ts +9 -0
  142. package/dist/dts/internal/errors.d.ts.map +1 -0
  143. package/dist/dts/internal/hydrate.d.ts +37 -0
  144. package/dist/dts/internal/hydrate.d.ts.map +1 -0
  145. package/dist/dts/internal/indexRefCounter.d.ts +6 -0
  146. package/dist/dts/internal/indexRefCounter.d.ts.map +1 -0
  147. package/dist/dts/internal/module-augmentation.d.ts +36 -0
  148. package/dist/dts/internal/module-augmentation.d.ts.map +1 -0
  149. package/dist/dts/internal/parser.d.ts +12 -0
  150. package/dist/dts/internal/parser.d.ts.map +1 -0
  151. package/dist/dts/internal/parts.d.ts +304 -0
  152. package/dist/dts/internal/parts.d.ts.map +1 -0
  153. package/dist/dts/internal/readAttribute.d.ts +9 -0
  154. package/dist/dts/internal/readAttribute.d.ts.map +1 -0
  155. package/dist/dts/internal/render.d.ts +30 -0
  156. package/dist/dts/internal/render.d.ts.map +1 -0
  157. package/dist/dts/internal/server.d.ts +31 -0
  158. package/dist/dts/internal/server.d.ts.map +1 -0
  159. package/dist/dts/internal/tokenizer.d.ts +3 -0
  160. package/dist/dts/internal/tokenizer.d.ts.map +1 -0
  161. package/dist/dts/internal/utils.d.ts +15 -0
  162. package/dist/dts/internal/utils.d.ts.map +1 -0
  163. package/dist/esm/Directive.js +64 -0
  164. package/dist/esm/Directive.js.map +1 -0
  165. package/dist/esm/ElementRef.js +72 -0
  166. package/dist/esm/ElementRef.js.map +1 -0
  167. package/dist/esm/ElementSource.js +237 -0
  168. package/dist/esm/ElementSource.js.map +1 -0
  169. package/dist/esm/Entry.js +2 -0
  170. package/dist/esm/Entry.js.map +1 -0
  171. package/dist/esm/EventHandler.js +52 -0
  172. package/dist/esm/EventHandler.js.map +1 -0
  173. package/dist/esm/Html.js +167 -0
  174. package/dist/esm/Html.js.map +1 -0
  175. package/dist/esm/HtmlChunk.js +274 -0
  176. package/dist/esm/HtmlChunk.js.map +1 -0
  177. package/dist/esm/Hydrate.js +37 -0
  178. package/dist/esm/Hydrate.js.map +1 -0
  179. package/dist/esm/Many.js +33 -0
  180. package/dist/esm/Many.js.map +1 -0
  181. package/dist/esm/Meta.js +29 -0
  182. package/dist/esm/Meta.js.map +1 -0
  183. package/dist/esm/Parser.js +342 -0
  184. package/dist/esm/Parser.js.map +1 -0
  185. package/dist/esm/Part.js +5 -0
  186. package/dist/esm/Part.js.map +1 -0
  187. package/dist/esm/Placeholder.js +30 -0
  188. package/dist/esm/Placeholder.js.map +1 -0
  189. package/dist/esm/Platform.js +41 -0
  190. package/dist/esm/Platform.js.map +1 -0
  191. package/dist/esm/Render.js +27 -0
  192. package/dist/esm/Render.js.map +1 -0
  193. package/dist/esm/RenderContext.js +113 -0
  194. package/dist/esm/RenderContext.js.map +1 -0
  195. package/dist/esm/RenderEvent.js +36 -0
  196. package/dist/esm/RenderEvent.js.map +1 -0
  197. package/dist/esm/RenderTemplate.js +26 -0
  198. package/dist/esm/RenderTemplate.js.map +1 -0
  199. package/dist/esm/Renderable.js +2 -0
  200. package/dist/esm/Renderable.js.map +1 -0
  201. package/dist/esm/Template.js +239 -0
  202. package/dist/esm/Template.js.map +1 -0
  203. package/dist/esm/TemplateInstance.js +43 -0
  204. package/dist/esm/TemplateInstance.js.map +1 -0
  205. package/dist/esm/Test.js +68 -0
  206. package/dist/esm/Test.js.map +1 -0
  207. package/dist/esm/Token.js +264 -0
  208. package/dist/esm/Token.js.map +1 -0
  209. package/dist/esm/Tokenizer.js +9 -0
  210. package/dist/esm/Tokenizer.js.map +1 -0
  211. package/dist/esm/Vitest.js +29 -0
  212. package/dist/esm/Vitest.js.map +1 -0
  213. package/dist/esm/index.js +65 -0
  214. package/dist/esm/index.js.map +1 -0
  215. package/dist/esm/internal/HydrateContext.js +7 -0
  216. package/dist/esm/internal/HydrateContext.js.map +1 -0
  217. package/dist/esm/internal/browser.js +102 -0
  218. package/dist/esm/internal/browser.js.map +1 -0
  219. package/dist/esm/internal/chunks.js +47 -0
  220. package/dist/esm/internal/chunks.js.map +1 -0
  221. package/dist/esm/internal/errors.js +15 -0
  222. package/dist/esm/internal/errors.js.map +1 -0
  223. package/dist/esm/internal/hydrate.js +165 -0
  224. package/dist/esm/internal/hydrate.js.map +1 -0
  225. package/dist/esm/internal/indexRefCounter.js +24 -0
  226. package/dist/esm/internal/indexRefCounter.js.map +1 -0
  227. package/dist/esm/internal/module-augmentation.js +2 -0
  228. package/dist/esm/internal/module-augmentation.js.map +1 -0
  229. package/dist/esm/internal/parser.js +493 -0
  230. package/dist/esm/internal/parser.js.map +1 -0
  231. package/dist/esm/internal/parts.js +291 -0
  232. package/dist/esm/internal/parts.js.map +1 -0
  233. package/dist/esm/internal/readAttribute.js +24 -0
  234. package/dist/esm/internal/readAttribute.js.map +1 -0
  235. package/dist/esm/internal/render.js +329 -0
  236. package/dist/esm/internal/render.js.map +1 -0
  237. package/dist/esm/internal/server.js +174 -0
  238. package/dist/esm/internal/server.js.map +1 -0
  239. package/dist/esm/internal/tokenizer.js +296 -0
  240. package/dist/esm/internal/tokenizer.js.map +1 -0
  241. package/dist/esm/internal/utils.js +52 -0
  242. package/dist/esm/internal/utils.js.map +1 -0
  243. package/dist/esm/package.json +4 -0
  244. package/package.json +242 -0
  245. package/src/Directive.ts +114 -0
  246. package/src/ElementRef.ts +123 -0
  247. package/src/ElementSource.ts +417 -0
  248. package/src/Entry.ts +28 -0
  249. package/src/EventHandler.ts +104 -0
  250. package/src/Html.ts +258 -0
  251. package/src/HtmlChunk.ts +346 -0
  252. package/src/Hydrate.ts +53 -0
  253. package/src/Many.ts +128 -0
  254. package/src/Meta.ts +32 -0
  255. package/src/Parser.ts +457 -0
  256. package/src/Part.ts +186 -0
  257. package/src/Placeholder.ts +70 -0
  258. package/src/Platform.ts +71 -0
  259. package/src/Render.ts +45 -0
  260. package/src/RenderContext.ts +221 -0
  261. package/src/RenderEvent.ts +67 -0
  262. package/src/RenderTemplate.ts +88 -0
  263. package/src/Renderable.ts +34 -0
  264. package/src/Template.ts +284 -0
  265. package/src/TemplateInstance.ts +83 -0
  266. package/src/Test.ts +151 -0
  267. package/src/Token.ts +269 -0
  268. package/src/Tokenizer.ts +10 -0
  269. package/src/Vitest.ts +61 -0
  270. package/src/index.ts +66 -0
  271. package/src/internal/HydrateContext.ts +23 -0
  272. package/src/internal/browser.ts +132 -0
  273. package/src/internal/chunks.ts +73 -0
  274. package/src/internal/errors.ts +11 -0
  275. package/src/internal/external.d.ts +11 -0
  276. package/src/internal/hydrate.ts +262 -0
  277. package/src/internal/indexRefCounter.ts +33 -0
  278. package/src/internal/module-augmentation.ts +48 -0
  279. package/src/internal/parser.ts +637 -0
  280. package/src/internal/parts.ts +527 -0
  281. package/src/internal/readAttribute.ts +28 -0
  282. package/src/internal/render.ts +529 -0
  283. package/src/internal/server.ts +293 -0
  284. package/src/internal/tokenizer.ts +338 -0
  285. package/src/internal/utils.ts +73 -0
@@ -0,0 +1,262 @@
1
+ import * as Fx from "@typed/fx/Fx"
2
+ import { makeSubject } from "@typed/fx/internal/core-subject"
3
+ import type { Rendered } from "@typed/wire"
4
+ import type { Cause } from "effect"
5
+ import { Effect } from "effect"
6
+ import * as ElementRef from "../ElementRef"
7
+ import type { Placeholder } from "../Placeholder"
8
+ import type { Renderable } from "../Renderable"
9
+ import type { RenderContext } from "../RenderContext"
10
+ import { DomRenderEvent } from "../RenderEvent"
11
+ import type { RenderTemplate } from "../RenderTemplate"
12
+ import { TemplateInstance } from "../TemplateInstance"
13
+ import { indexRefCounter } from "./indexRefCounter"
14
+
15
+ import { unsafeGet } from "@typed/context"
16
+
17
+ import type { Template } from "../Template"
18
+ import { CouldNotFindCommentError, CouldNotFindRootElement } from "./errors"
19
+ import { HydrateContext } from "./HydrateContext"
20
+ import { buildParts, getBrowserEntry, renderTemplate, renderValues } from "./render"
21
+ import {
22
+ findPath,
23
+ getPreviousNodes,
24
+ isComment,
25
+ isCommentWithValue,
26
+ isHtmlElement,
27
+ type ParentChildNodes
28
+ } from "./utils"
29
+
30
+ // TODO: Handle missing comment errors
31
+
32
+ /**
33
+ * Here for "standard" browser rendering, a TemplateInstance is effectively a live
34
+ * view into the contents rendered by the Template.
35
+ */
36
+ export const hydrateTemplate: (document: Document, ctx: RenderContext) => RenderTemplate =
37
+ (document, renderContext) =>
38
+ <Values extends ReadonlyArray<Renderable<any, any>>, T extends Rendered = Rendered>(
39
+ templateStrings: TemplateStringsArray,
40
+ values: Values,
41
+ providedRef?: ElementRef.ElementRef<T>
42
+ ) => {
43
+ return Effect.gen(function*(_) {
44
+ const context = yield* _(Effect.context<never>())
45
+ const hydrateCtx = unsafeGet(context, HydrateContext)
46
+
47
+ // If we're not longer hydrating, just render normally
48
+ if (!hydrateCtx.hydrate) {
49
+ return yield* _(renderTemplate(document, renderContext)(templateStrings, values, providedRef))
50
+ }
51
+
52
+ const elementRef = providedRef || (yield* _(ElementRef.make<T>()))
53
+ const events = Fx.map(elementRef, DomRenderEvent)
54
+ const errors = makeSubject<Placeholder.Error<Values[number]>, never>()
55
+
56
+ const { getParts, template, where, wire } = getHydrateEntry({
57
+ ...hydrateCtx,
58
+ document,
59
+ renderContext,
60
+ elementRef,
61
+ strings: templateStrings,
62
+ onCause: errors.onFailure
63
+ })
64
+ const parts = yield* _(getParts)
65
+
66
+ // If there are parts we need to render them before constructing our Wire
67
+ if (parts.length > 0) {
68
+ const refCounter = yield* _(indexRefCounter(parts.length))
69
+
70
+ // Do the work
71
+ yield* _(renderValues(values, parts, refCounter, errors.onFailure, (index: number): HydrateContext => ({
72
+ where,
73
+ rootIndex: index,
74
+ parentTemplate: template,
75
+ hydrate: true
76
+ })))
77
+
78
+ // Wait for initial work to be completed
79
+ yield* _(refCounter.wait)
80
+ }
81
+
82
+ hydrateCtx.hydrate = false
83
+
84
+ // Set the element when it is ready
85
+ yield* _(ElementRef.set(elementRef, wire as T))
86
+
87
+ // Return the Template instance
88
+ return TemplateInstance(Fx.merge([events, errors]), elementRef)
89
+ })
90
+ }
91
+
92
+ export function findRootParentChildNodes(where: HTMLElement): ParentChildNodes {
93
+ const childNodes = findRootChildNodes(where)
94
+
95
+ return {
96
+ parentNode: where,
97
+ childNodes
98
+ }
99
+ }
100
+
101
+ const START = "typed-start"
102
+ const END = "typed-end"
103
+
104
+ // Finds all of the childNodes between the "typed-start" and "typed-end" comments
105
+ export function findRootChildNodes(where: HTMLElement): Array<Node> {
106
+ const childNodes: Array<Node> = []
107
+
108
+ let start = 0
109
+ let end = childNodes.length
110
+
111
+ for (let i = 0; i < where.childNodes.length; i++) {
112
+ const node = where.childNodes[i]
113
+
114
+ if (node.nodeType === node.COMMENT_NODE) {
115
+ if (node.nodeValue === START) {
116
+ start = i
117
+ break
118
+ }
119
+ }
120
+ }
121
+
122
+ for (let i = where.childNodes.length - 1; i >= start; i--) {
123
+ const node = where.childNodes[i]
124
+
125
+ if (node.nodeType === node.COMMENT_NODE) {
126
+ if (node.nodeValue === END) {
127
+ end = i
128
+ break
129
+ }
130
+ }
131
+ }
132
+
133
+ for (let i = start + 1; i <= end; i++) {
134
+ childNodes.push(where.childNodes[i])
135
+ }
136
+
137
+ return childNodes
138
+ }
139
+
140
+ export function findTemplateResultPartChildNodes(
141
+ where: ParentChildNodes,
142
+ parentTemplate: Template,
143
+ childTemplate: Template | null,
144
+ partIndex: number,
145
+ childIndex?: number
146
+ ) {
147
+ const [, path] = parentTemplate.parts[partIndex]
148
+ const parentNode = findPath(where, path) as HTMLElement
149
+ const childNodes = findPartChildNodes(parentNode, childTemplate?.hash, partIndex)
150
+ const parentChildNodes = {
151
+ parentNode,
152
+ childNodes: childIndex !== undefined ? [childNodes[childIndex]] : childNodes
153
+ }
154
+
155
+ return parentChildNodes
156
+ }
157
+
158
+ export function findPartChildNodes(
159
+ { childNodes }: ParentChildNodes,
160
+ hash: string | null | undefined,
161
+ partIndex: number
162
+ ) {
163
+ const [comment, index] = findPartComment(childNodes, partIndex)
164
+
165
+ const nodes: Array<Node> = []
166
+ const previousHoleValue = `hole${partIndex - 1}`
167
+
168
+ if (hash) {
169
+ for (let i = index; i > -1; --i) {
170
+ const node = childNodes[i]
171
+
172
+ if (isHtmlElement(node) && node.dataset.typed === hash) {
173
+ nodes.unshift(node)
174
+ } else if (partIndex > 0 && isCommentWithValue(node, previousHoleValue)) {
175
+ break
176
+ }
177
+ }
178
+ } else {
179
+ return [...getPreviousNodes(comment, partIndex), comment]
180
+ }
181
+
182
+ if (nodes.length === 0) {
183
+ throw new CouldNotFindRootElement(partIndex)
184
+ }
185
+
186
+ nodes.push(comment)
187
+
188
+ return nodes
189
+ }
190
+
191
+ export function findPartComment(childNodes: ArrayLike<Node>, partIndex: number) {
192
+ const search = partIndex === -1 ? `typed-end` : `hole${partIndex}`
193
+
194
+ for (let i = 0; i < childNodes.length; ++i) {
195
+ const node = childNodes[i]
196
+
197
+ if (isCommentWithValue(node, search)) {
198
+ return [node, i] as const
199
+ }
200
+ }
201
+
202
+ throw new CouldNotFindCommentError(partIndex)
203
+ }
204
+
205
+ export function getHydrateEntry({
206
+ childIndex,
207
+ document,
208
+ elementRef,
209
+ onCause,
210
+ parentTemplate,
211
+ renderContext,
212
+ rootIndex,
213
+ strings,
214
+ where
215
+ }: {
216
+ document: Document
217
+ renderContext: RenderContext
218
+ where: ParentChildNodes
219
+ rootIndex: number
220
+ parentTemplate: Template | null
221
+ strings: TemplateStringsArray
222
+ elementRef: ElementRef.ElementRef<any>
223
+ onCause: (cause: Cause.Cause<any>) => Effect.Effect<never, never, void>
224
+ childIndex?: number
225
+ }) {
226
+ const { template } = getBrowserEntry(document, renderContext, strings)
227
+
228
+ if (parentTemplate) {
229
+ where = findTemplateResultPartChildNodes(where, parentTemplate, template, rootIndex, childIndex)
230
+ }
231
+
232
+ const getParts = buildParts(document, renderContext, template, where, elementRef, onCause, true)
233
+
234
+ const wire = (() => {
235
+ if (!parentTemplate) {
236
+ const childNodes = Array.from(where.childNodes).filter((node) =>
237
+ isComment(node) ? !isCommentWithValue(node, END) : true
238
+ )
239
+
240
+ if (childNodes.length === 1) {
241
+ return childNodes[0]
242
+ }
243
+
244
+ return childNodes
245
+ }
246
+
247
+ if (where.childNodes.length === 1) {
248
+ return where.childNodes[0]
249
+ }
250
+
251
+ return Array.from(where.childNodes).filter(
252
+ (node) => !isCommentWithValue(node, `hole${rootIndex}`)
253
+ )
254
+ })()
255
+
256
+ return {
257
+ template,
258
+ wire,
259
+ getParts,
260
+ where
261
+ } as const
262
+ }
@@ -0,0 +1,33 @@
1
+ import * as Deferred from "effect/Deferred"
2
+ import * as Effect from "effect/Effect"
3
+
4
+ export type IndexRefCounter = {
5
+ release: (index: number) => Effect.Effect<never, never, void>
6
+ wait: Effect.Effect<never, never, void>
7
+ }
8
+
9
+ /**
10
+ * @internal
11
+ */
12
+ export function indexRefCounter(expected: number): Effect.Effect<
13
+ never,
14
+ never,
15
+ IndexRefCounter
16
+ > {
17
+ return Effect.map(Deferred.make<never, void>(), (deferred) => {
18
+ const indexes = new Set<number>(Array.from({ length: expected }, (_, i) => i))
19
+
20
+ function release(index: number) {
21
+ return Effect.suspend(() => {
22
+ if (indexes.delete(index) && indexes.size === 0) {
23
+ return Deferred.succeed(deferred, undefined)
24
+ } else return Effect.unit
25
+ })
26
+ }
27
+
28
+ return {
29
+ release,
30
+ wait: Deferred.await(deferred)
31
+ }
32
+ })
33
+ }
@@ -0,0 +1,48 @@
1
+ import type { Placeholder } from "../Placeholder"
2
+
3
+ declare global {
4
+ export interface String extends Placeholder<never, never, string> {}
5
+
6
+ export interface Number extends Placeholder<never, never, number> {}
7
+
8
+ export interface Boolean extends Placeholder<never, never, boolean> {}
9
+
10
+ export interface Symbol extends Placeholder<never, never, symbol> {}
11
+
12
+ export interface BigInt extends Placeholder<never, never, bigint> {}
13
+
14
+ export interface Array<T> extends
15
+ Placeholder<
16
+ Placeholder.Context<T>,
17
+ Placeholder.Error<T>,
18
+ Array<Placeholder.Success<T>>
19
+ >
20
+ {}
21
+
22
+ export interface ReadonlyArray<T> extends
23
+ Placeholder<
24
+ Placeholder.Context<T>,
25
+ Placeholder.Error<T>,
26
+ ReadonlyArray<Placeholder.Success<T>>
27
+ >
28
+ {}
29
+
30
+ // DOM types
31
+ export interface Node extends Placeholder<never, never, Node> {}
32
+
33
+ export interface DocumentFragment extends Placeholder<never, never, DocumentFragment> {}
34
+
35
+ export interface Element extends Placeholder<never, never, Element> {}
36
+
37
+ export interface HTMLElement extends Placeholder<never, never, HTMLElement> {}
38
+
39
+ export interface SVGElement extends Placeholder<never, never, SVGElement> {}
40
+ }
41
+
42
+ declare module "@typed/fx/Fx" {
43
+ export interface Fx<R, E, A> extends Placeholder<R, E, A> {}
44
+ }
45
+
46
+ declare module "effect/Effect" {
47
+ export interface Effect<R, E, A> extends Placeholder<R, E, A> {}
48
+ }