@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.
- package/dist/cjs/Html.js +12 -2
- package/dist/cjs/Html.js.map +1 -1
- package/dist/cjs/Hydrate.js +15 -7
- package/dist/cjs/Hydrate.js.map +1 -1
- package/dist/cjs/Render.js +17 -7
- package/dist/cjs/Render.js.map +1 -1
- package/dist/cjs/Test.js +10 -5
- package/dist/cjs/Test.js.map +1 -1
- package/dist/cjs/internal/hydrate.js +10 -5
- package/dist/cjs/internal/hydrate.js.map +1 -1
- package/dist/cjs/internal/render.js +8 -5
- package/dist/cjs/internal/render.js.map +1 -1
- package/dist/dts/Html.d.ts +13 -3
- package/dist/dts/Html.d.ts.map +1 -1
- package/dist/dts/Hydrate.d.ts +12 -4
- package/dist/dts/Hydrate.d.ts.map +1 -1
- package/dist/dts/Platform.d.ts +1 -1
- package/dist/dts/Platform.d.ts.map +1 -1
- package/dist/dts/Render.d.ts +16 -5
- package/dist/dts/Render.d.ts.map +1 -1
- package/dist/dts/Test.d.ts +6 -10
- package/dist/dts/Test.d.ts.map +1 -1
- package/dist/dts/internal/hydrate.d.ts.map +1 -1
- package/dist/dts/internal/render.d.ts.map +1 -1
- package/dist/esm/Html.js +13 -2
- package/dist/esm/Html.js.map +1 -1
- package/dist/esm/Hydrate.js +11 -5
- package/dist/esm/Hydrate.js.map +1 -1
- package/dist/esm/Render.js +13 -5
- package/dist/esm/Render.js.map +1 -1
- package/dist/esm/Test.js +12 -7
- package/dist/esm/Test.js.map +1 -1
- package/dist/esm/internal/hydrate.js +9 -6
- package/dist/esm/internal/hydrate.js.map +1 -1
- package/dist/esm/internal/render.js +7 -6
- package/dist/esm/internal/render.js.map +1 -1
- package/package.json +2 -2
- package/src/Html.ts +26 -7
- package/src/Hydrate.ts +39 -12
- package/src/Platform.ts +1 -1
- package/src/Render.ts +51 -14
- package/src/Test.ts +23 -13
- package/src/internal/hydrate.ts +9 -6
- 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 {
|
|
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
|
|
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,
|
|
56
|
+
): Fx.Fx<ToRendered<T>, E, R | RenderTemplate | RenderContext.RenderContext | RootElement> {
|
|
28
57
|
return Fx.fromFxEffect(Effect.contextWith((context) => {
|
|
29
|
-
const [
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
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
|
-
|
|
47
|
-
|
|
78
|
+
Exclude<
|
|
79
|
+
Exclude<R, Scope.Scope>,
|
|
80
|
+
RenderTemplate | RenderContext.RenderContext | CurrentEnvironment | DomServices
|
|
81
|
+
>
|
|
48
82
|
> {
|
|
49
|
-
return
|
|
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
|
|
6
|
-
import
|
|
7
|
-
import
|
|
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<
|
|
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(
|
|
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(
|
|
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.
|
|
237
|
-
Effect.
|
|
246
|
+
Effect.provide(hydrateLayer(window, { skipRenderScheduling: true })),
|
|
247
|
+
Effect.forkScoped
|
|
238
248
|
)
|
|
239
249
|
|
|
240
250
|
const test: TestHydrate<E, Elements> = {
|
package/src/internal/hydrate.ts
CHANGED
|
@@ -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
|
|
47
|
-
const
|
|
48
|
-
const
|
|
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
|
-
|
|
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
|
package/src/internal/render.ts
CHANGED
|
@@ -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
|
|
578
|
-
const
|
|
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 (
|
|
610
|
-
|
|
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
|
|