@typed/template 0.7.0 → 0.8.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 (44) hide show
  1. package/dist/cjs/Html.js +12 -2
  2. package/dist/cjs/Html.js.map +1 -1
  3. package/dist/cjs/Hydrate.js +15 -7
  4. package/dist/cjs/Hydrate.js.map +1 -1
  5. package/dist/cjs/Render.js +17 -7
  6. package/dist/cjs/Render.js.map +1 -1
  7. package/dist/cjs/Test.js +10 -5
  8. package/dist/cjs/Test.js.map +1 -1
  9. package/dist/cjs/internal/hydrate.js +10 -5
  10. package/dist/cjs/internal/hydrate.js.map +1 -1
  11. package/dist/cjs/internal/render.js +8 -5
  12. package/dist/cjs/internal/render.js.map +1 -1
  13. package/dist/dts/Html.d.ts +13 -3
  14. package/dist/dts/Html.d.ts.map +1 -1
  15. package/dist/dts/Hydrate.d.ts +12 -4
  16. package/dist/dts/Hydrate.d.ts.map +1 -1
  17. package/dist/dts/Platform.d.ts +1 -1
  18. package/dist/dts/Platform.d.ts.map +1 -1
  19. package/dist/dts/Render.d.ts +16 -5
  20. package/dist/dts/Render.d.ts.map +1 -1
  21. package/dist/dts/Test.d.ts +6 -10
  22. package/dist/dts/Test.d.ts.map +1 -1
  23. package/dist/dts/internal/hydrate.d.ts.map +1 -1
  24. package/dist/dts/internal/render.d.ts.map +1 -1
  25. package/dist/esm/Html.js +13 -2
  26. package/dist/esm/Html.js.map +1 -1
  27. package/dist/esm/Hydrate.js +11 -5
  28. package/dist/esm/Hydrate.js.map +1 -1
  29. package/dist/esm/Render.js +13 -5
  30. package/dist/esm/Render.js.map +1 -1
  31. package/dist/esm/Test.js +12 -7
  32. package/dist/esm/Test.js.map +1 -1
  33. package/dist/esm/internal/hydrate.js +9 -6
  34. package/dist/esm/internal/hydrate.js.map +1 -1
  35. package/dist/esm/internal/render.js +7 -6
  36. package/dist/esm/internal/render.js.map +1 -1
  37. package/package.json +2 -2
  38. package/src/Html.ts +26 -7
  39. package/src/Hydrate.ts +39 -12
  40. package/src/Platform.ts +1 -1
  41. package/src/Render.ts +51 -14
  42. package/src/Test.ts +23 -13
  43. package/src/internal/hydrate.ts +9 -6
  44. package/src/internal/render.ts +7 -8
package/src/Render.ts CHANGED
@@ -4,13 +4,17 @@
4
4
 
5
5
  import * as Context from "@typed/context"
6
6
  import { Document } from "@typed/dom/Document"
7
+ import type { DomServices, DomServicesElementParams } from "@typed/dom/DomServices"
8
+ import type { GlobalThis } from "@typed/dom/GlobalThis"
7
9
  import { RootElement } from "@typed/dom/RootElement"
10
+ import type { CurrentEnvironment } from "@typed/environment"
8
11
  import * as Fx from "@typed/fx/Fx"
9
12
  import { type Rendered } from "@typed/wire"
10
- import type { Layer, Scope } from "effect"
13
+ import type { Scope } from "effect"
14
+ import { Layer } from "effect"
11
15
  import * as Effect from "effect/Effect"
12
16
  import { attachRoot, renderTemplate } from "./internal/render.js"
13
- import { RenderContext } from "./RenderContext.js"
17
+ import * as RenderContext from "./RenderContext.js"
14
18
  import { type RenderEvent } from "./RenderEvent.js"
15
19
  import { RenderTemplate } from "./RenderTemplate.js"
16
20
 
@@ -19,32 +23,65 @@ import { RenderTemplate } from "./RenderTemplate.js"
19
23
  */
20
24
  export type ToRendered<T extends RenderEvent | null> = T extends null ? Rendered | null : Rendered
21
25
 
26
+ /**
27
+ * @since 1.0.0
28
+ */
29
+ export const renderLayer = (
30
+ window: Window & GlobalThis,
31
+ options?: DomServicesElementParams & { readonly skipRenderScheduling?: boolean }
32
+ ): Layer.Layer<
33
+ | RenderTemplate
34
+ | RenderContext.RenderContext
35
+ | CurrentEnvironment
36
+ | DomServices
37
+ > =>
38
+ Layer.provideMerge(
39
+ RenderTemplate.layer(Effect.contextWith((context: Context.Context<Document | RenderContext.RenderContext>) => {
40
+ const [document, ctx] = Context.getMany(
41
+ context,
42
+ Document,
43
+ RenderContext.RenderContext
44
+ )
45
+
46
+ return renderTemplate(document, ctx)
47
+ })),
48
+ RenderContext.dom(window, options)
49
+ )
50
+
22
51
  /**
23
52
  * @since 1.0.0
24
53
  */
25
54
  export function render<R, E, T extends RenderEvent | null>(
26
55
  rendered: Fx.Fx<T, E, R>
27
- ): Fx.Fx<ToRendered<T>, E, Exclude<R, RenderTemplate> | Document | RenderContext | RootElement> {
56
+ ): Fx.Fx<ToRendered<T>, E, R | RenderTemplate | RenderContext.RenderContext | RootElement> {
28
57
  return Fx.fromFxEffect(Effect.contextWith((context) => {
29
- const [document, ctx, { rootElement }] = Context.getMany(context, Document, RenderContext, RootElement)
30
-
31
- return Fx.provideService(
32
- Fx.mapEffect(rendered, (what) => attachRoot(ctx.renderCache, rootElement, what)),
33
- RenderTemplate,
34
- renderTemplate(document, ctx)
58
+ const [ctx, { rootElement }] = Context.getMany(
59
+ context,
60
+ RenderContext.RenderContext,
61
+ RootElement
35
62
  )
63
+
64
+ return Fx.mapEffect(rendered, (what) => attachRoot(ctx.renderCache, rootElement, what))
36
65
  }))
37
66
  }
38
67
 
39
68
  /**
40
69
  * @since 1.0.0
41
70
  */
42
- export function renderLayer<R, E, T extends RenderEvent | null>(
43
- rendered: Fx.Fx<T, E, R>
71
+ export function renderToLayer<R, E, T extends RenderEvent | null>(
72
+ rendered: Fx.Fx<T, E, R>,
73
+ window: Window & GlobalThis = globalThis.window,
74
+ options?: DomServicesElementParams & { readonly skipRenderScheduling?: boolean }
44
75
  ): Layer.Layer<
76
+ RenderTemplate | RenderContext.RenderContext | CurrentEnvironment | DomServices,
45
77
  never,
46
- never,
47
- Document | RenderContext | RootElement | Exclude<Exclude<R, RenderTemplate>, Scope.Scope>
78
+ Exclude<
79
+ Exclude<R, Scope.Scope>,
80
+ RenderTemplate | RenderContext.RenderContext | CurrentEnvironment | DomServices
81
+ >
48
82
  > {
49
- return Fx.drainLayer(Fx.switchMapCause(render(rendered), (e) => Fx.fromEffect(Effect.logError(e))))
83
+ return Layer.provideMerge(
84
+ Fx.drainLayer(Fx.switchMapCause(render(rendered), (e) => Fx.fromEffect(Effect.logError(e)))),
85
+ renderLayer(window, options)
86
+ )
50
87
  }
package/src/Test.ts CHANGED
@@ -2,15 +2,16 @@
2
2
  * @since 1.0.0
3
3
  */
4
4
  import type { Document } from "@typed/dom/Document"
5
- import type { DomServices, DomServicesElementParams } from "@typed/dom/DomServices"
6
- import type { GlobalThis } from "@typed/dom/GlobalThis"
7
- import type { Window } from "@typed/dom/Window"
5
+ import { type DomServices, domServices, type DomServicesElementParams } from "@typed/dom/DomServices"
6
+ import { GlobalThis } from "@typed/dom/GlobalThis"
7
+ import { Window } from "@typed/dom/Window"
8
8
  import type { CurrentEnvironment } from "@typed/environment"
9
9
  import * as Fx from "@typed/fx/Fx"
10
10
  import * as RefArray from "@typed/fx/RefArray"
11
11
  import * as RefSubject from "@typed/fx/RefSubject"
12
12
  import * as Sink from "@typed/fx/Sink"
13
13
  import { type Rendered } from "@typed/wire"
14
+ import { Layer } from "effect"
14
15
  import * as Cause from "effect/Cause"
15
16
  import * as Effect from "effect/Effect"
16
17
  import * as Either from "effect/Either"
@@ -18,11 +19,11 @@ import * as Fiber from "effect/Fiber"
18
19
  import type * as Scope from "effect/Scope"
19
20
  import * as ElementRef from "./ElementRef.js"
20
21
  import { ROOT_CSS_SELECTOR } from "./ElementSource.js"
21
- import { renderToHtmlString } from "./Html.js"
22
- import { hydrate } from "./Hydrate.js"
22
+ import { renderToHtmlString, serverLayer } from "./Html.js"
23
+ import { hydrate, hydrateLayer } from "./Hydrate.js"
23
24
  import { adjustTime, isCommentWithValue } from "./internal/utils.js"
24
- import { render } from "./Render.js"
25
- import * as RenderContext from "./RenderContext.js"
25
+ import { render, renderLayer } from "./Render.js"
26
+ import type * as RenderContext from "./RenderContext.js"
26
27
  import type { RenderEvent } from "./RenderEvent.js"
27
28
  import type { RenderTemplate } from "./RenderTemplate.js"
28
29
 
@@ -62,7 +63,7 @@ export function testRender<E, R>(
62
63
  ): Effect.Effect<
63
64
  TestRender<E>,
64
65
  never,
65
- Scope.Scope | Exclude<Exclude<R, RenderTemplate>, RenderContext.RenderContext | CurrentEnvironment | DomServices>
66
+ Scope.Scope | Exclude<R, RenderTemplate | RenderContext.RenderContext | CurrentEnvironment | DomServices>
66
67
  > {
67
68
  return Effect.gen(function*(_) {
68
69
  const window = yield* _(getOrMakeWindow(options))
@@ -83,7 +84,7 @@ export function testRender<E, R>(
83
84
  (rendered) => ElementRef.set(elementRef, rendered)
84
85
  )),
85
86
  Effect.forkScoped,
86
- Effect.provide(RenderContext.dom(window, { skipRenderScheduling: true }))
87
+ Effect.provide(renderLayer(window, { skipRenderScheduling: true }))
87
88
  )
88
89
 
89
90
  const test: TestRender<E> = {
@@ -192,14 +193,23 @@ export function testHydrate<R, E, Elements>(
192
193
  options?:
193
194
  & HappyDOMOptions
194
195
  & { readonly [K in keyof DomServicesElementParams]?: (document: Document) => DomServicesElementParams[K] }
195
- ) {
196
+ ): Effect.Effect<
197
+ TestHydrate<E, Elements>,
198
+ E,
199
+ Scope.Scope | Exclude<R, RenderTemplate | RenderContext.RenderContext | CurrentEnvironment | DomServices>
200
+ > {
196
201
  return Effect.gen(function*(_) {
197
202
  const window = yield* _(getOrMakeWindow(options))
198
203
  const { body } = window.document
199
204
 
200
205
  const html = yield* _(
201
206
  renderToHtmlString(fx),
202
- Effect.provide(RenderContext.server)
207
+ Effect.provide(serverLayer.pipe(
208
+ // Add DomServices to the layer for the types
209
+ Layer.provideMerge(domServices()),
210
+ Layer.provideMerge(Window.layer(window)),
211
+ Layer.provideMerge(GlobalThis.layer(window))
212
+ ))
203
213
  )
204
214
 
205
215
  body.innerHTML = html
@@ -233,8 +243,8 @@ export function testHydrate<R, E, Elements>(
233
243
  ),
234
244
  (rendered) => ElementRef.set(elementRef, rendered)
235
245
  )),
236
- Effect.forkScoped,
237
- Effect.provide(RenderContext.dom(window, { skipRenderScheduling: true }))
246
+ Effect.provide(hydrateLayer(window, { skipRenderScheduling: true })),
247
+ Effect.forkScoped
238
248
  )
239
249
 
240
250
  const test: TestHydrate<E, Elements> = {
@@ -10,7 +10,7 @@ import { indexRefCounter2 } from "./indexRefCounter.js"
10
10
 
11
11
  import { unsafeGet } from "@typed/context"
12
12
 
13
- import { Either, ExecutionStrategy, Exit } from "effect"
13
+ import { Either, ExecutionStrategy, Exit, Runtime } from "effect"
14
14
  import * as Scope from "effect/Scope"
15
15
  import type { Template } from "../Template.js"
16
16
  import { CouldNotFindCommentError, CouldNotFindManyCommentError, CouldNotFindRootElement } from "./errors.js"
@@ -43,9 +43,10 @@ export const hydrateTemplate: (document: Document, ctx: RenderContext) => Render
43
43
  ): Fx.Fx<RenderEvent, Placeholder.Error<Values[number]>, Scope.Scope | Placeholder.Context<Values[number]>> => {
44
44
  return Fx.make((sink) =>
45
45
  Effect.gen(function*(_) {
46
- const context = yield* _(Effect.context<Scope.Scope>())
47
- const hydrateCtx = unsafeGet(context, HydrateContext)
48
- const parentScope = unsafeGet(context, Scope.Scope)
46
+ const runtime = yield* _(Effect.runtime<Placeholder.Context<Values[number]> | Scope.Scope>())
47
+ const runFork = Runtime.runFork(runtime)
48
+ const hydrateCtx = unsafeGet(runtime.context, HydrateContext)
49
+ const parentScope = unsafeGet(runtime.context, Scope.Scope)
49
50
  const scope = yield* _(Scope.fork(parentScope, ExecutionStrategy.sequential))
50
51
 
51
52
  // If we're not longer hydrating, just render normally
@@ -78,7 +79,7 @@ export const hydrateTemplate: (document: Document, ctx: RenderContext) => Render
78
79
 
79
80
  const refCounter = yield* _(indexRefCounter2())
80
81
  const ctx: RenderPartContext = {
81
- context,
82
+ context: runtime.context,
82
83
  document,
83
84
  eventSource: makeEventSource(),
84
85
  expected: 0,
@@ -105,7 +106,9 @@ export const hydrateTemplate: (document: Document, ctx: RenderContext) => Render
105
106
 
106
107
  // Fork any effects necessary
107
108
  if (effects.length > 0) {
108
- yield* _(Effect.forkAll(effects))
109
+ for (let i = 0; i < effects.length; i++) {
110
+ runFork(effects[i], { scope })
111
+ }
109
112
  }
110
113
 
111
114
  // Set the element when it is ready
@@ -3,7 +3,7 @@ import * as Sink from "@typed/fx/Sink"
3
3
  import { TypeId } from "@typed/fx/TypeId"
4
4
  import type { Rendered } from "@typed/wire"
5
5
  import { persistent } from "@typed/wire"
6
- import { Effect, ExecutionStrategy, Exit } from "effect"
6
+ import { Effect, ExecutionStrategy, Exit, Runtime } from "effect"
7
7
  import type { Cause } from "effect/Cause"
8
8
  import type { Chunk } from "effect/Chunk"
9
9
  import * as Context from "effect/Context"
@@ -574,13 +574,14 @@ export const renderTemplate: (document: Document, renderContext: RenderContext)
574
574
  sink
575
575
  ) => {
576
576
  return Effect.gen(function*(_) {
577
- const context = yield* _(Effect.context<Scope.Scope | Placeholder.Context<Values[number]>>())
578
- const parentScope = Context.get(context, Scope.Scope)
577
+ const runtime = yield* _(Effect.runtime<Scope.Scope | Placeholder.Context<Values[number]>>())
578
+ const runFork = Runtime.runFork(runtime)
579
+ const parentScope = Context.get(runtime.context, Scope.Scope)
579
580
  const scope = yield* _(Scope.fork(parentScope, ExecutionStrategy.sequential))
580
581
  const refCounter = yield* _(indexRefCounter2())
581
582
  const content = document.importNode(entry.content, true)
582
583
  const ctx: RenderPartContext = {
583
- context,
584
+ context: runtime.context,
584
585
  document,
585
586
  eventSource: makeEventSource(),
586
587
  expected: 0,
@@ -606,10 +607,8 @@ export const renderTemplate: (document: Document, renderContext: RenderContext)
606
607
 
607
608
  // Fork any effects necessary
608
609
  if (effects.length > 0) {
609
- for (const eff of effects) {
610
- yield* _(
611
- Effect.forkIn(Effect.catchAllCause(eff, ctx.onCause), scope)
612
- )
610
+ for (let i = 0; i < effects.length; ++i) {
611
+ runFork(effects[i], { scope })
613
612
  }
614
613
  }
615
614