@typed/template 0.2.0 → 0.3.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 (213) hide show
  1. package/dist/cjs/Directive.js +1 -1
  2. package/dist/cjs/Directive.js.map +1 -1
  3. package/dist/cjs/ElementRef.js +23 -13
  4. package/dist/cjs/ElementRef.js.map +1 -1
  5. package/dist/cjs/ElementSource.js +16 -18
  6. package/dist/cjs/ElementSource.js.map +1 -1
  7. package/dist/cjs/EventHandler.js +1 -1
  8. package/dist/cjs/EventHandler.js.map +1 -1
  9. package/dist/cjs/Html.js +31 -32
  10. package/dist/cjs/Html.js.map +1 -1
  11. package/dist/cjs/HtmlChunk.js +4 -1
  12. package/dist/cjs/HtmlChunk.js.map +1 -1
  13. package/dist/cjs/Hydrate.js +1 -1
  14. package/dist/cjs/Hydrate.js.map +1 -1
  15. package/dist/cjs/Many.js +14 -13
  16. package/dist/cjs/Many.js.map +1 -1
  17. package/dist/cjs/Parser.js +11 -323
  18. package/dist/cjs/Parser.js.map +1 -1
  19. package/dist/cjs/Placeholder.js +3 -3
  20. package/dist/cjs/Placeholder.js.map +1 -1
  21. package/dist/cjs/Platform.js +4 -4
  22. package/dist/cjs/Platform.js.map +1 -1
  23. package/dist/cjs/Render.js +1 -1
  24. package/dist/cjs/Render.js.map +1 -1
  25. package/dist/cjs/RenderContext.js +48 -27
  26. package/dist/cjs/RenderContext.js.map +1 -1
  27. package/dist/cjs/RenderTemplate.js +2 -17
  28. package/dist/cjs/RenderTemplate.js.map +1 -1
  29. package/dist/cjs/Template.js +27 -1
  30. package/dist/cjs/Template.js.map +1 -1
  31. package/dist/cjs/TemplateInstance.js +2 -2
  32. package/dist/cjs/TemplateInstance.js.map +1 -1
  33. package/dist/cjs/Test.js +20 -7
  34. package/dist/cjs/Test.js.map +1 -1
  35. package/dist/cjs/index.js +0 -12
  36. package/dist/cjs/index.js.map +1 -1
  37. package/dist/cjs/internal/EventSource.js +95 -0
  38. package/dist/cjs/internal/EventSource.js.map +1 -0
  39. package/dist/cjs/internal/browser.js +11 -11
  40. package/dist/cjs/internal/browser.js.map +1 -1
  41. package/dist/cjs/internal/hydrate.js +49 -50
  42. package/dist/cjs/internal/hydrate.js.map +1 -1
  43. package/dist/cjs/internal/indexRefCounter.js +49 -2
  44. package/dist/cjs/internal/indexRefCounter.js.map +1 -1
  45. package/dist/cjs/internal/parser.js +60 -17
  46. package/dist/cjs/internal/parser.js.map +1 -1
  47. package/dist/cjs/internal/parts.js +128 -28
  48. package/dist/cjs/internal/parts.js.map +1 -1
  49. package/dist/cjs/internal/render.js +486 -53
  50. package/dist/cjs/internal/render.js.map +1 -1
  51. package/dist/cjs/internal/server.js +5 -2
  52. package/dist/cjs/internal/server.js.map +1 -1
  53. package/dist/dts/Directive.d.ts.map +1 -1
  54. package/dist/dts/ElementRef.d.ts +4 -2
  55. package/dist/dts/ElementRef.d.ts.map +1 -1
  56. package/dist/dts/ElementSource.d.ts +10 -5
  57. package/dist/dts/ElementSource.d.ts.map +1 -1
  58. package/dist/dts/EventHandler.d.ts.map +1 -1
  59. package/dist/dts/Html.d.ts +1 -1
  60. package/dist/dts/Html.d.ts.map +1 -1
  61. package/dist/dts/HtmlChunk.d.ts.map +1 -1
  62. package/dist/dts/Many.d.ts +13 -11
  63. package/dist/dts/Many.d.ts.map +1 -1
  64. package/dist/dts/Parser.d.ts +3 -6
  65. package/dist/dts/Parser.d.ts.map +1 -1
  66. package/dist/dts/Part.d.ts +13 -3
  67. package/dist/dts/Part.d.ts.map +1 -1
  68. package/dist/dts/Placeholder.d.ts +2 -2
  69. package/dist/dts/Placeholder.d.ts.map +1 -1
  70. package/dist/dts/Render.d.ts +2 -1
  71. package/dist/dts/Render.d.ts.map +1 -1
  72. package/dist/dts/RenderContext.d.ts +5 -4
  73. package/dist/dts/RenderContext.d.ts.map +1 -1
  74. package/dist/dts/RenderTemplate.d.ts +2 -16
  75. package/dist/dts/RenderTemplate.d.ts.map +1 -1
  76. package/dist/dts/Renderable.d.ts +2 -2
  77. package/dist/dts/Renderable.d.ts.map +1 -1
  78. package/dist/dts/Template.d.ts +21 -3
  79. package/dist/dts/Template.d.ts.map +1 -1
  80. package/dist/dts/TemplateInstance.d.ts +3 -2
  81. package/dist/dts/TemplateInstance.d.ts.map +1 -1
  82. package/dist/dts/Test.d.ts +4 -6
  83. package/dist/dts/Test.d.ts.map +1 -1
  84. package/dist/dts/index.d.ts +0 -4
  85. package/dist/dts/index.d.ts.map +1 -1
  86. package/dist/dts/internal/EventSource.d.ts +12 -0
  87. package/dist/dts/internal/EventSource.d.ts.map +1 -0
  88. package/dist/dts/internal/browser.d.ts.map +1 -1
  89. package/dist/dts/internal/hydrate.d.ts +5 -5
  90. package/dist/dts/internal/hydrate.d.ts.map +1 -1
  91. package/dist/dts/internal/indexRefCounter.d.ts +5 -0
  92. package/dist/dts/internal/indexRefCounter.d.ts.map +1 -1
  93. package/dist/dts/internal/module-augmentation.d.ts +0 -4
  94. package/dist/dts/internal/module-augmentation.d.ts.map +1 -1
  95. package/dist/dts/internal/parser.d.ts +8 -0
  96. package/dist/dts/internal/parser.d.ts.map +1 -1
  97. package/dist/dts/internal/parts.d.ts +66 -56
  98. package/dist/dts/internal/parts.d.ts.map +1 -1
  99. package/dist/dts/internal/render.d.ts +7 -7
  100. package/dist/dts/internal/render.d.ts.map +1 -1
  101. package/dist/dts/internal/server.d.ts.map +1 -1
  102. package/dist/esm/Directive.js +1 -1
  103. package/dist/esm/Directive.js.map +1 -1
  104. package/dist/esm/ElementRef.js +12 -7
  105. package/dist/esm/ElementRef.js.map +1 -1
  106. package/dist/esm/ElementSource.js +16 -13
  107. package/dist/esm/ElementSource.js.map +1 -1
  108. package/dist/esm/EventHandler.js +1 -1
  109. package/dist/esm/EventHandler.js.map +1 -1
  110. package/dist/esm/Html.js +29 -24
  111. package/dist/esm/Html.js.map +1 -1
  112. package/dist/esm/HtmlChunk.js +6 -1
  113. package/dist/esm/HtmlChunk.js.map +1 -1
  114. package/dist/esm/Hydrate.js +1 -1
  115. package/dist/esm/Hydrate.js.map +1 -1
  116. package/dist/esm/Many.js +14 -10
  117. package/dist/esm/Many.js.map +1 -1
  118. package/dist/esm/Parser.js +6 -335
  119. package/dist/esm/Parser.js.map +1 -1
  120. package/dist/esm/Placeholder.js +2 -2
  121. package/dist/esm/Placeholder.js.map +1 -1
  122. package/dist/esm/Platform.js +2 -2
  123. package/dist/esm/Platform.js.map +1 -1
  124. package/dist/esm/Render.js +1 -1
  125. package/dist/esm/Render.js.map +1 -1
  126. package/dist/esm/RenderContext.js +38 -17
  127. package/dist/esm/RenderContext.js.map +1 -1
  128. package/dist/esm/RenderTemplate.js +2 -12
  129. package/dist/esm/RenderTemplate.js.map +1 -1
  130. package/dist/esm/Template.js +24 -0
  131. package/dist/esm/Template.js.map +1 -1
  132. package/dist/esm/TemplateInstance.js +2 -2
  133. package/dist/esm/TemplateInstance.js.map +1 -1
  134. package/dist/esm/Test.js +20 -7
  135. package/dist/esm/Test.js.map +1 -1
  136. package/dist/esm/index.js +0 -4
  137. package/dist/esm/index.js.map +1 -1
  138. package/dist/esm/internal/EventSource.js +91 -0
  139. package/dist/esm/internal/EventSource.js.map +1 -0
  140. package/dist/esm/internal/browser.js +12 -12
  141. package/dist/esm/internal/browser.js.map +1 -1
  142. package/dist/esm/internal/hydrate.js +45 -46
  143. package/dist/esm/internal/hydrate.js.map +1 -1
  144. package/dist/esm/internal/indexRefCounter.js +50 -2
  145. package/dist/esm/internal/indexRefCounter.js.map +1 -1
  146. package/dist/esm/internal/parser.js +84 -17
  147. package/dist/esm/internal/parser.js.map +1 -1
  148. package/dist/esm/internal/parts.js +110 -27
  149. package/dist/esm/internal/parts.js.map +1 -1
  150. package/dist/esm/internal/render.js +476 -58
  151. package/dist/esm/internal/render.js.map +1 -1
  152. package/dist/esm/internal/server.js +5 -4
  153. package/dist/esm/internal/server.js.map +1 -1
  154. package/package.json +10 -26
  155. package/src/Directive.ts +1 -1
  156. package/src/ElementRef.ts +18 -14
  157. package/src/ElementSource.ts +62 -47
  158. package/src/EventHandler.ts +1 -1
  159. package/src/Html.ts +58 -57
  160. package/src/HtmlChunk.ts +15 -1
  161. package/src/Hydrate.ts +1 -1
  162. package/src/Many.ts +53 -43
  163. package/src/Parser.ts +10 -453
  164. package/src/Part.ts +15 -3
  165. package/src/Placeholder.ts +4 -4
  166. package/src/Platform.ts +2 -2
  167. package/src/Render.ts +7 -2
  168. package/src/RenderContext.ts +47 -19
  169. package/src/RenderTemplate.ts +9 -54
  170. package/src/Renderable.ts +2 -1
  171. package/src/Template.ts +26 -0
  172. package/src/TemplateInstance.ts +9 -9
  173. package/src/Test.ts +40 -21
  174. package/src/index.ts +0 -4
  175. package/src/internal/EventSource.ts +153 -0
  176. package/src/internal/browser.ts +26 -25
  177. package/src/internal/hydrate.ts +68 -61
  178. package/src/internal/indexRefCounter.ts +63 -2
  179. package/src/internal/module-augmentation.ts +0 -4
  180. package/src/internal/parser.ts +92 -19
  181. package/src/internal/parts.ts +158 -73
  182. package/src/internal/render.ts +701 -89
  183. package/src/internal/server.ts +5 -3
  184. package/Token/package.json +0 -6
  185. package/Tokenizer/package.json +0 -6
  186. package/dist/cjs/Token.js +0 -270
  187. package/dist/cjs/Token.js.map +0 -1
  188. package/dist/cjs/Tokenizer.js +0 -18
  189. package/dist/cjs/Tokenizer.js.map +0 -1
  190. package/dist/cjs/internal/readAttribute.js +0 -34
  191. package/dist/cjs/internal/readAttribute.js.map +0 -1
  192. package/dist/cjs/internal/tokenizer.js +0 -264
  193. package/dist/cjs/internal/tokenizer.js.map +0 -1
  194. package/dist/dts/Token.d.ts +0 -202
  195. package/dist/dts/Token.d.ts.map +0 -1
  196. package/dist/dts/Tokenizer.d.ts +0 -6
  197. package/dist/dts/Tokenizer.d.ts.map +0 -1
  198. package/dist/dts/internal/readAttribute.d.ts +0 -9
  199. package/dist/dts/internal/readAttribute.d.ts.map +0 -1
  200. package/dist/dts/internal/tokenizer.d.ts +0 -3
  201. package/dist/dts/internal/tokenizer.d.ts.map +0 -1
  202. package/dist/esm/Token.js +0 -264
  203. package/dist/esm/Token.js.map +0 -1
  204. package/dist/esm/Tokenizer.js +0 -9
  205. package/dist/esm/Tokenizer.js.map +0 -1
  206. package/dist/esm/internal/readAttribute.js +0 -24
  207. package/dist/esm/internal/readAttribute.js.map +0 -1
  208. package/dist/esm/internal/tokenizer.js +0 -296
  209. package/dist/esm/internal/tokenizer.js.map +0 -1
  210. package/src/Token.ts +0 -269
  211. package/src/Tokenizer.ts +0 -10
  212. package/src/internal/readAttribute.ts +0 -28
  213. package/src/internal/tokenizer.ts +0 -338
@@ -1,18 +1,13 @@
1
- import type { Context } from "@typed/context"
2
- import * as Fx from "@typed/fx/Fx"
3
- import { WithContext } from "@typed/fx/Sink"
4
- import { isText, type Rendered } from "@typed/wire"
1
+ import { isText } from "@typed/wire"
5
2
  import type { Cause } from "effect/Cause"
3
+ import * as Data from "effect/Data"
6
4
  import * as Effect from "effect/Effect"
7
5
  import { equals } from "effect/Equal"
8
- import { strict } from "effect/Equivalence"
9
- import type { Equivalence } from "effect/Equivalence"
10
- import * as Fiber from "effect/Fiber"
6
+ import * as Equivalence from "effect/Equivalence"
11
7
  import * as ReadonlyArray from "effect/ReadonlyArray"
12
8
  import type { Scope } from "effect/Scope"
13
- import * as SynchronizedRef from "effect/SynchronizedRef"
14
- import type { ElementRef } from "../ElementRef.js"
15
9
  import type { ElementSource } from "../ElementSource.js"
10
+ import type { EventHandler } from "../EventHandler.js"
16
11
  import { unescape } from "../HtmlChunk.js"
17
12
  import type {
18
13
  AttributePart,
@@ -23,6 +18,7 @@ import type {
23
18
  EventPart,
24
19
  NodePart,
25
20
  Part,
21
+ PropertiesPart,
26
22
  PropertyPart,
27
23
  RefPart,
28
24
  SparseAttributePart,
@@ -35,7 +31,7 @@ import type {
35
31
  import type { RenderContext } from "../RenderContext.js"
36
32
  import { findHoleComment } from "./utils.js"
37
33
 
38
- const strictEq = strict<any>()
34
+ const strictEq = Equivalence.strict<any>()
39
35
 
40
36
  const base = <T extends Part["_tag"]>(tag: T) =>
41
37
  class Base {
@@ -51,7 +47,7 @@ const base = <T extends Part["_tag"]>(tag: T) =>
51
47
  }
52
48
  ) => Effect.Effect<Scope, never, void>,
53
49
  public value: Extract<Part, { readonly _tag: T }>["value"],
54
- readonly eq: Equivalence<Extract<Part, { readonly _tag: T }>["value"]> = equals
50
+ readonly eq: Equivalence.Equivalence<Extract<Part, { readonly _tag: T }>["value"]> = equals
55
51
  ) {
56
52
  this.update = this.update.bind(this)
57
53
  }
@@ -64,7 +60,7 @@ const base = <T extends Part["_tag"]>(tag: T) =>
64
60
  return Effect.unit
65
61
  }
66
62
 
67
- return Effect.tap(
63
+ return Effect.flatMap(
68
64
  this.commit.call(this, {
69
65
  previous,
70
66
  value,
@@ -291,73 +287,20 @@ function diffDataSet(
291
287
  }
292
288
  }
293
289
 
294
- export class EventPartImpl extends base("event") implements EventPart {
290
+ export class EventPartImpl implements EventPart {
291
+ readonly _tag = "event"
292
+ readonly value: EventPart["value"] = null
293
+
295
294
  constructor(
296
295
  readonly name: string,
296
+ readonly index: number,
297
+ readonly source: ElementSource<any>,
297
298
  readonly onCause: <E>(cause: Cause<E>) => Effect.Effect<never, never, unknown>,
298
- index: number,
299
- commit: EventPartImpl["commit"],
300
- value: EventPart["value"]
299
+ readonly addEventListener: <Ev extends Event>(handler: EventHandler<never, never, Ev>) => void
301
300
  ) {
302
- super(index, commit, value, strictEq)
303
- }
304
-
305
- static browser<T extends Rendered, E>(
306
- name: string,
307
- index: number,
308
- ref: ElementRef<T>,
309
- element: HTMLElement | SVGElement,
310
- onCause: (cause: Cause<E>) => Effect.Effect<never, never, unknown>
311
- ): Effect.Effect<unknown, never, void> {
312
- return withSwitchFork((fork, ctx) => {
313
- const source = ref.query(element)
314
-
315
- return Effect.succeed(
316
- new EventPartImpl(
317
- name,
318
- onCause as any,
319
- index,
320
- ({ value }) => {
321
- return value
322
- ? Fx.run(
323
- source.events(name as keyof HTMLElementEventMap | keyof SVGElementEventMap, value.options),
324
- WithContext(onCause, value.handler)
325
- ).pipe(
326
- Effect.provide(ctx),
327
- fork
328
- )
329
- : fork(Effect.unit)
330
- },
331
- null
332
- )
333
- )
334
- })
335
301
  }
336
302
  }
337
303
 
338
- function withScopedFork<R, E, A>(f: (fork: Fx.ScopedFork) => Effect.Effect<R, E, A>): Effect.Effect<R | Scope, E, A> {
339
- return Effect.scopeWith((scope) => f(Effect.forkIn(scope)))
340
- }
341
-
342
- // Ensures only a single fiber is executing
343
- function withSwitchFork<R, E, A>(
344
- f: (fork: Fx.FxFork, ctx: Context<R | Scope>) => Effect.Effect<R, E, A>
345
- ): Effect.Effect<R | Scope, E, A> {
346
- return Effect.contextWithEffect((ctx) =>
347
- withScopedFork((fork) =>
348
- Effect.flatMap(
349
- SynchronizedRef.make<Fiber.Fiber<never, void>>(Fiber.unit),
350
- (ref) =>
351
- f((effect) =>
352
- SynchronizedRef.updateAndGetEffect(
353
- ref,
354
- (fiber) => Effect.flatMap(Fiber.interrupt(fiber), () => fork(effect))
355
- ), ctx)
356
- )
357
- )
358
- )
359
- }
360
-
361
304
  export class NodePartImpl extends base("node") implements NodePart {}
362
305
 
363
306
  export class PropertyPartImpl extends base("property") implements PropertyPart {
@@ -403,6 +346,147 @@ export class TextPartImpl extends base("text") implements TextPart {
403
346
  strictEq
404
347
  )
405
348
  }
349
+
350
+ static fromText(text: Text, index: number, ctx: RenderContext) {
351
+ return new TextPartImpl(
352
+ index,
353
+ ({ part, value }) => ctx.queue.add(part, () => text.nodeValue = value ?? null),
354
+ text.nodeValue,
355
+ strictEq
356
+ )
357
+ }
358
+
359
+ static getOrCreateText(document: Document, index: number, element: Element) {
360
+ const comment = findHoleComment(element, index)
361
+
362
+ return comment.previousSibling && isText(comment.previousSibling)
363
+ ? comment.previousSibling.nodeValue
364
+ : document.createTextNode("")
365
+ }
366
+ }
367
+
368
+ export class PropertiesPartImpl extends base("properties") implements PropertiesPart {
369
+ constructor(
370
+ index: number,
371
+ commit: PropertiesPartImpl["commit"],
372
+ value: PropertiesPartImpl["value"]
373
+ ) {
374
+ super(index, commit, value, equals)
375
+ }
376
+
377
+ getValue(value: unknown): unknown {
378
+ if (value == null) return null
379
+ return Data.struct(value)
380
+ }
381
+
382
+ static browser(index: number, element: HTMLElement | SVGElement, ctx: RenderContext) {
383
+ return new PropertiesPartImpl(
384
+ index,
385
+ ({ part, previous, value }) =>
386
+ ctx.queue.add(
387
+ part,
388
+ () => {
389
+ const diff = diffProperties(previous, value)
390
+ if (diff) {
391
+ const { added, removed } = diff
392
+
393
+ removed.forEach((nv) => removeNameValue(element, nv))
394
+ added.forEach((nv) => {
395
+ if ((nv.name[0] === "o" && nv.name[1] === "n") || nv.name[0] === "@") return
396
+
397
+ return addNameValue(element, nv)
398
+ })
399
+ }
400
+ }
401
+ ),
402
+ {}
403
+ )
404
+ }
405
+ }
406
+
407
+ function removeNameValue(element: HTMLElement | SVGElement, { name, type }: NameValue) {
408
+ switch (type) {
409
+ case "attr":
410
+ case "bool":
411
+ return element.removeAttribute(name)
412
+ case "prop":
413
+ return delete (element as any)[name]
414
+ }
415
+ }
416
+
417
+ function addNameValue(element: HTMLElement | SVGElement, { name, type, value }: NameValue) {
418
+ switch (type) {
419
+ case "attr":
420
+ return value == null ? element.removeAttribute(name) : element.setAttribute(name, value)
421
+ case "bool":
422
+ return value == null ? element.removeAttribute(name) : element.toggleAttribute(name, value)
423
+ case "prop":
424
+ return value == null ? (delete (element as any)[name]) : (element as any)[name] = value
425
+ }
426
+ }
427
+
428
+ type AttrNameValue = {
429
+ readonly type: "attr"
430
+ readonly name: string
431
+ readonly value: string
432
+ }
433
+
434
+ type BoolAttrNameValue = {
435
+ readonly type: "bool"
436
+ readonly name: string
437
+ readonly value: boolean
438
+ }
439
+
440
+ type PropNameValue = {
441
+ readonly type: "prop"
442
+ readonly name: string
443
+ readonly value: unknown
444
+ }
445
+
446
+ type NameValue = AttrNameValue | BoolAttrNameValue | PropNameValue
447
+
448
+ function diffProperties(
449
+ a: Record<string, unknown> | null | undefined,
450
+ b: Record<string, unknown> | null | undefined
451
+ ): { added: Array<NameValue>; removed: ReadonlyArray<NameValue> } | null {
452
+ if (!a) {
453
+ if (b) {
454
+ return { added: Object.entries(b).flatMap(([k, v]) => fromKeyValue(k, v)), removed: [] }
455
+ } else return null
456
+ } else if (!b) {
457
+ return { added: [], removed: Object.entries(a).flatMap(([k, v]) => fromKeyValue(k, v)) }
458
+ } else {
459
+ const { added, removed, unchanged } = diffStrings(Object.keys(a), Object.keys(b))
460
+
461
+ return {
462
+ added: added.concat(unchanged).flatMap((k) => fromKeyValue(k, b[k])),
463
+ removed: removed.flatMap((k) => fromKeyValue(k, a[k]))
464
+ }
465
+ }
466
+ }
467
+
468
+ function fromKeyValue(name: string, value: unknown): Array<NameValue> {
469
+ if (name[0] === ".") {
470
+ return value == null ? [] : [{
471
+ type: "prop",
472
+ name: name.slice(1),
473
+ value
474
+ }]
475
+ } else if (typeof value === "boolean") {
476
+ return [{
477
+ type: "bool",
478
+ name,
479
+ value
480
+ }]
481
+ } else {
482
+ if (name[0] === "o" || name[1] === "n") return []
483
+
484
+ return value == null ? [] : [{
485
+ type: "attr",
486
+ name,
487
+ value: String(value)
488
+ }]
489
+ }
406
490
  }
407
491
 
408
492
  const sparse = <T extends SparsePart["_tag"]>(tag: T) =>
@@ -418,7 +502,8 @@ const sparse = <T extends SparsePart["_tag"]>(tag: T) =>
418
502
  }
419
503
  ) => Effect.Effect<Scope, never, void>,
420
504
  public value: SparseAttributeValues<Extract<SparsePart, { readonly _tag: T }>["parts"]>,
421
- readonly eq: Equivalence<SparseAttributeValues<Extract<SparsePart, { readonly _tag: T }>["parts"]>> = equals
505
+ readonly eq: Equivalence.Equivalence<SparseAttributeValues<Extract<SparsePart, { readonly _tag: T }>["parts"]>> =
506
+ equals
422
507
  ) {}
423
508
 
424
509
  update = (value: this["value"]) => {