@typed/svelte 1.0.0-beta.7 → 1.0.0-beta.8
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/LICENSE +21 -0
- package/README.md +22 -12
- package/dist/Reactive.d.ts +13 -3
- package/dist/Reactive.d.ts.map +1 -1
- package/dist/Reactive.js +4 -8
- package/dist/Typed.client.js +2 -2
- package/dist/Typed.d.ts +1 -1
- package/dist/Typed.d.ts.map +1 -1
- package/dist/Typed.server.js +3 -3
- package/dist/ViewOptions.d.ts +2 -2
- package/dist/ViewOptions.d.ts.map +1 -1
- package/dist/internal/Dom.d.ts.map +1 -1
- package/dist/internal/Dom.js +2 -5
- package/dist/view.d.ts +2 -1
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +14 -7
- package/package.json +11 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-present The Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Svelte 5 components inside Typed templates, and Typed renderables inside Svelte. Both directions create their own `display: contents` hosts, preserve SSR node identity during hydration, and release subscriptions with their rendering scope. The caller keeps ownership of its runtime.
|
|
4
4
|
|
|
5
|
+
`view` requires `RandomValues` from `@typed/id/RandomValues` for automatic IDs. This service stays in the returned `Fx` requirements. Provide `RandomValues.Default` (or your own implementation) alongside the renderer at the application boundary; the integration does not choose an entropy source.
|
|
6
|
+
|
|
5
7
|
## Svelte in Typed
|
|
6
8
|
|
|
7
9
|
```ts
|
|
10
|
+
import { RandomValues } from "@typed/id/RandomValues";
|
|
8
11
|
import { Fx, RefSubject } from "@typed/fx";
|
|
9
12
|
import { html } from "@typed/template/RenderTemplate";
|
|
10
13
|
import { DomRenderTemplate, render } from "@typed/template/Render";
|
|
@@ -14,15 +17,15 @@ import Counter from "./Counter.svelte";
|
|
|
14
17
|
|
|
15
18
|
const application = Fx.gen(function* () {
|
|
16
19
|
const props = yield* RefSubject.make({ label: "Count" });
|
|
17
|
-
const content = html`<main>${view(Counter, props
|
|
20
|
+
const content = html`<main>${view(Counter, props)}</main>`;
|
|
18
21
|
|
|
19
22
|
return render(content, document.body);
|
|
20
|
-
}).pipe(Fx.drainLayer, Layer.provide(DomRenderTemplate));
|
|
23
|
+
}).pipe(Fx.drainLayer, Layer.provide(Layer.merge(DomRenderTemplate, RandomValues.Default)));
|
|
21
24
|
|
|
22
25
|
const program = Layer.launch(application);
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
`view(component, props,
|
|
28
|
+
`view(component, props, options?)` accepts a props object, `Effect`, `Stream`, or `Fx` (including `RefSubject`). Component props determine the required shape; the source's errors and required services remain in the returned `Fx`. It mounts once and updates a Svelte store, preserving component state. Once the first render event is published, the ambient Scope keeps the component live even if a consumer takes only that event. Cancellation before the first output releases pending acquisition. Nested published islands remain owned by their rendering Scope even when a sibling prevents the parent from publishing. A finite props source leaves the component mounted until cleanup. `context`, `intro`, `outro`, `recover`, `idPrefix`, `csp`, and `transformError` forward to the corresponding Svelte API.
|
|
26
29
|
|
|
27
30
|
Typed supplies the host through a native element ref. Svelte mounts at that ref and schedules its own commit. For a nested island, refs can run before Typed places the surrounding parent; `onMount` is not a guarantee that the parent is attached. The first Typed output describes the host, and subsequent props update the same component.
|
|
28
31
|
|
|
@@ -31,17 +34,24 @@ Typed supplies the host through a native element ref. Svelte mounts at that ref
|
|
|
31
34
|
## Server rendering and hydration
|
|
32
35
|
|
|
33
36
|
```ts
|
|
37
|
+
import * as Layer from "effect/Layer";
|
|
38
|
+
import { RandomValues } from "@typed/id/RandomValues";
|
|
34
39
|
import { view } from "@typed/svelte";
|
|
35
40
|
import { Fx } from "@typed/fx";
|
|
36
41
|
import { HtmlRenderTemplate, renderToHtml, renderToHtmlString } from "@typed/template/Html";
|
|
37
42
|
import { Effect } from "effect";
|
|
38
43
|
|
|
39
|
-
const page = view(Counter, { label: "Count" }
|
|
40
|
-
const chunks = renderToHtml(page).pipe(
|
|
44
|
+
const page = view(Counter, { label: "Count" });
|
|
45
|
+
const chunks = renderToHtml(page).pipe(
|
|
46
|
+
Fx.provide(Layer.merge(HtmlRenderTemplate, RandomValues.Default)),
|
|
47
|
+
);
|
|
41
48
|
|
|
42
49
|
// Collect a complete string when needed, including static generation.
|
|
43
50
|
const body = await Effect.runPromise(
|
|
44
|
-
renderToHtmlString(page).pipe(
|
|
51
|
+
renderToHtmlString(page).pipe(
|
|
52
|
+
Effect.provide(Layer.merge(HtmlRenderTemplate, RandomValues.Default)),
|
|
53
|
+
Effect.scoped,
|
|
54
|
+
),
|
|
45
55
|
);
|
|
46
56
|
```
|
|
47
57
|
|
|
@@ -49,7 +59,7 @@ Prefer `renderToHtml` when the response can consume chunks. The application obse
|
|
|
49
59
|
|
|
50
60
|
The surrounding Typed template and Svelte host stream before the component is ready. Svelte's public server renderer returns a complete `body` and `head`, so the component body arrives together after its first props value and asynchronous rendering finish. Application service requirements and source errors stay in the Effect type. `onHead` is optional and receives application `<svelte:head>` output; omit it when the component has no head content.
|
|
51
61
|
|
|
52
|
-
On the client, pass the same Typed template and its server root to `render`. Hydration is automatic. Typed creates an ordinary `div` host through its native template path. The
|
|
62
|
+
On the client, pass the same Typed template and its server root to `render`. Hydration is automatic. Typed creates an ordinary `div` host and a child range through its native template path. The HTML backend renders Svelte's serialized body into that range; the DOM backend hands its children to Svelte for mounting or hydration. Client and server need matching initial props and component structure. Host identity is generated automatically and restored from server markup during hydration; `options.id` remains an explicit override. Explicit ids must be nonempty and unique across the page; the host id also defaults Svelte's server `idPrefix`.
|
|
53
63
|
|
|
54
64
|
`@typed/svelte` and `@typed/svelte/Typed.svelte` import in Node without `document` or a `.svelte` loader. The package publishes separate compiled client and server components selected through native package conditions. Application Svelte components use their normal Svelte compilation.
|
|
55
65
|
|
|
@@ -67,10 +77,10 @@ On the client, pass the same Typed template and its server root to `render`. Hyd
|
|
|
67
77
|
</button>`;
|
|
68
78
|
</script>
|
|
69
79
|
|
|
70
|
-
<Typed
|
|
80
|
+
<Typed value={content} />
|
|
71
81
|
```
|
|
72
82
|
|
|
73
|
-
`Typed` accepts any Typed `Renderable` as its `
|
|
83
|
+
`Typed` accepts any Typed `Renderable` as its `value`, including primitive values, templates, `Effect`, `Stream`, and `Fx`. Its automatically created `div` host has `display: contents`. The optional `id` prop defaults to Svelte's `$props.id()`, stable across SSR and hydration. Views without application services need no runtime. The optional `runtime` prop or nearest `provideRuntime` context supplies application services when needed. Runtime changes or view replacements close the previous rendering scope before starting the next.
|
|
74
84
|
|
|
75
85
|
Use Svelte's own APIs for SSR, static generation, and hydration:
|
|
76
86
|
|
|
@@ -86,7 +96,7 @@ const app = hydrate(App, { target, props: { count: 0 } });
|
|
|
86
96
|
|
|
87
97
|
The component supplies `HtmlRenderTemplate` and Scope during native Svelte SSR, then supplies `DomRenderTemplate` through its Svelte attachment in the browser. It awaits Typed's HTML rendering. Each response closes its observation scope while leaving a supplied runtime owned by the caller. Svelte retains the server HTML at the opaque boundary, and Typed hydrates its original nodes. Client-only `mount` starts the live view normally. No manually prepared HTML or integration rendering helper is needed. The package compiles its asynchronous component, so consumers do not need to enable Svelte's experimental async compiler option. As with other asynchronous Svelte components, use `await render(...)` on the server.
|
|
88
98
|
|
|
89
|
-
`onReady` fires after the first Typed output attaches; `onError` receives typed failures or renderer defects as an Effect `Cause`. Without `onError`, the host dispatches `typed:error`. Normal interruption is silent. Updating these callbacks or `stopPropagation` preserves the current Typed render; replacing `runtime` or `
|
|
99
|
+
`onReady` fires after the first Typed output attaches; `onError` receives typed failures or renderer defects as an Effect `Cause`. Without `onError`, the host dispatches `typed:error`. Normal interruption is silent. Updating these callbacks or `stopPropagation` preserves the current Typed render; replacing `runtime` or `value` closes and replaces it. Component cleanup never calls `runtime.dispose()`.
|
|
90
100
|
|
|
91
101
|
For an existing element, the lower-level `attachment(runtime, view, options?)` from `@typed/svelte/Attachment` works with Svelte's `{@attach}` syntax. The component is the usual choice when you want automatic hosting and SSR.
|
|
92
102
|
|
|
@@ -97,8 +107,8 @@ For an existing element, the lower-level `attachment(runtime, view, options?)` f
|
|
|
97
107
|
- `fromReadable(store)` returns an `Fx` that subscribes when observed and unsubscribes on interruption.
|
|
98
108
|
- These store conversions accept non-failing sources because Svelte stores have no error channel. `useSource` and `useAsyncData` expose failures and pending states through Typed's `AsyncData` model.
|
|
99
109
|
- `provideRuntime`, `provideServices`, `useRuntime`, and `useService` use Svelte context and borrowed runtime facades. Reactive runtime stores propagate provider replacements.
|
|
100
|
-
- `useSource`, `useAsyncData`, and `useRefSubject` own work for the Svelte component lifetime.
|
|
101
|
-
- `useRefSubject(ref,
|
|
110
|
+
- `useSource`, `useAsyncData`, and `useRefSubject` own work for the Svelte component lifetime. Browser observation starts after mount; server rendering never starts source effects. `useSource` and `useAsyncData` render the provided `initial` snapshot.
|
|
111
|
+
- `useRefSubject(ref, options?)` observes through `useSource` after mount and starts with `undefined` and `NoData`. Values and failures arrive through the normal RefSubject subscription; it does not inspect or execute the ref during component setup. Pass `{ initial: snapshot }` on both server and client when hydration needs an explicit first value; this also narrows the store value from `A | undefined` to `A`. Its `set` and `update` methods accept `A`, return `Promise<Exit>`, and publish after the RefSubject's serialized transaction settles. Read and write failures remain visible in `.state` when native bindings ignore those results. Runtime replacement and unmount interrupt pending writes.
|
|
102
112
|
- `useNavigation`, `useLocation`, `useCurrentPath`, `useCurrentRoute`, `useRoute`, and `provideCurrentRoute` use Typed's actual Navigation, Matcher, decoded params, and structural CurrentRoute services.
|
|
103
113
|
|
|
104
114
|
`useRoute(route, { currentRoute })` accepts a `CurrentRouteTree` or native Svelte readable store. Omission matches relative to the ambient mount and returns `None` outside it. An explicit tree replaces that mount and applies its prefix once; unmatched paths inside it return `None`, while paths outside it retain Typed's `RouteNotFound` failure. Updating the root store restarts observation with the new context. `provideCurrentRoute` continues to set the structural context inherited by descendants.
|
package/dist/Reactive.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type * as Context from "effect/Context";
|
|
|
4
4
|
import * as Effect from "effect/Effect";
|
|
5
5
|
import * as Exit from "effect/Exit";
|
|
6
6
|
import * as Scope from "effect/Scope";
|
|
7
|
-
import { type Readable
|
|
7
|
+
import { type Readable } from "svelte/store";
|
|
8
8
|
import { type AsyncState } from "./AsyncData.js";
|
|
9
9
|
import { type RuntimeSource } from "./Runtime.js";
|
|
10
10
|
import { type Source } from "./Source.js";
|
|
@@ -30,15 +30,25 @@ export declare function useAsyncData<A, E, E2 = never, R = never, ER = never>(so
|
|
|
30
30
|
/** Reads any Effect service using the same runtime, SSR, and failure contract. */
|
|
31
31
|
export declare function useService<I, A, ER = never>(service: Context.Service<I, A>, options?: SourceOptions<A, never, I, ER>): AsyncState<A, ER>;
|
|
32
32
|
/** A native writable whose transactional writes settle with typed Exit results. */
|
|
33
|
-
export interface RefSubjectStore<A, E> extends
|
|
33
|
+
export interface RefSubjectStore<A, E, Initial = undefined> extends Readable<A | Initial> {
|
|
34
34
|
readonly state: AsyncState<A, E>;
|
|
35
35
|
readonly set: (value: A) => Promise<Exit.Exit<A, E>>;
|
|
36
36
|
readonly update: (f: (value: A) => A) => Promise<Exit.Exit<A, E>>;
|
|
37
37
|
}
|
|
38
|
+
export interface RefSubjectOptions<A, E, R, ER = never> extends Omit<SourceOptions<A, E, R, ER>, "initial"> {
|
|
39
|
+
/** Overrides the first server/client snapshot, including for an uninitialized ref. */
|
|
40
|
+
readonly initial?: A;
|
|
41
|
+
}
|
|
38
42
|
/**
|
|
39
43
|
* Observes any RefSubject, including hydrated refs with typed failures. Writes
|
|
40
44
|
* use its serialized transactions; failures also reach `state` when a native
|
|
41
45
|
* binding ignores the returned Exit. Unmount/runtime replacement cancels writes.
|
|
46
|
+
* The first subscription receives the optional initial value or `undefined`.
|
|
47
|
+
* Lazy initializers only start after mount; `initial` can seed matching SSR and
|
|
48
|
+
* hydration values without executing application effects during rendering.
|
|
42
49
|
*/
|
|
43
|
-
export declare function useRefSubject<A, E = never, R = never, ER = never>(ref: RefSubject.RefSubject<A, E, R>,
|
|
50
|
+
export declare function useRefSubject<A, E = never, R = never, ER = never>(ref: RefSubject.RefSubject<A, E, R>, options: RefSubjectOptions<A, E, R, ER> & {
|
|
51
|
+
readonly initial: A;
|
|
52
|
+
}): RefSubjectStore<A, E | ER, never>;
|
|
53
|
+
export declare function useRefSubject<A, E = never, R = never, ER = never>(ref: RefSubject.RefSubject<A, E, R>, options?: RefSubjectOptions<A, E, R, ER>): RefSubjectStore<A, E | ER>;
|
|
44
54
|
//# sourceMappingURL=Reactive.d.ts.map
|
package/dist/Reactive.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Reactive.d.ts","sourceRoot":"","sources":["../src/Reactive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,UAAU,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AAIpC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAA0B,KAAK,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"Reactive.d.ts","sourceRoot":"","sources":["../src/Reactive.ts"],"names":[],"mappings":"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"}
|
package/dist/Reactive.js
CHANGED
|
@@ -109,17 +109,13 @@ export function useAsyncData(source, options = {}) {
|
|
|
109
109
|
export function useService(service, options = {}) {
|
|
110
110
|
return useSource(Effect.service(service), options);
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
* Observes any RefSubject, including hydrated refs with typed failures. Writes
|
|
114
|
-
* use its serialized transactions; failures also reach `state` when a native
|
|
115
|
-
* binding ignores the returned Exit. Unmount/runtime replacement cancels writes.
|
|
116
|
-
*/
|
|
117
|
-
export function useRefSubject(ref, initial, options = {}) {
|
|
112
|
+
export function useRefSubject(ref, options = {}) {
|
|
118
113
|
const runtime = options.runtime
|
|
119
114
|
? asReadable(options.runtime)
|
|
120
115
|
: useRuntime();
|
|
121
|
-
const
|
|
122
|
-
const
|
|
116
|
+
const initial = "initial" in options ? AsyncData.success(options.initial) : AsyncData.NoData;
|
|
117
|
+
const observed = useSource(ref, { runtime, initial });
|
|
118
|
+
const values = writable(Option.getOrUndefined(AsyncData.getSuccess(initial)));
|
|
123
119
|
const result = writable(undefined);
|
|
124
120
|
let writes = Scope.makeUnsafe("parallel");
|
|
125
121
|
let active = false;
|
package/dist/Typed.client.js
CHANGED
|
@@ -27,7 +27,7 @@ export default function Typed($$anchor, $$props) {
|
|
|
27
27
|
|
|
28
28
|
const render = $.derived(() => {
|
|
29
29
|
const selected = $.get(selectedRuntime);
|
|
30
|
-
const current = $$props.
|
|
30
|
+
const current = $$props.value;
|
|
31
31
|
|
|
32
32
|
return (root) => attachment(selected, current, {
|
|
33
33
|
stopPropagation: false,
|
|
@@ -57,7 +57,7 @@ export default function Typed($$anchor, $$props) {
|
|
|
57
57
|
initialHtml;
|
|
58
58
|
|
|
59
59
|
var $$promises = $.run([
|
|
60
|
-
async () => initialHtml = await renderSnapshot($.get(selectedRuntime), $$props.
|
|
60
|
+
async () => initialHtml = await renderSnapshot($.get(selectedRuntime), $$props.value)
|
|
61
61
|
]);
|
|
62
62
|
|
|
63
63
|
var div = root_1();
|
package/dist/Typed.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { AttachmentOptions } from "./Attachment.js";
|
|
|
6
6
|
/** Props for the Svelte component that embeds a Typed renderable. */
|
|
7
7
|
export interface TypedProps<V extends Renderable.Any, ER = never> extends AttachmentOptions<Renderable.Error<V> | ER> {
|
|
8
8
|
readonly runtime?: Runtime<Exclude<Exclude<Renderable.Services<V>, RenderTemplate>, Scope.Scope>, ER>;
|
|
9
|
-
readonly
|
|
9
|
+
readonly value: V;
|
|
10
10
|
/** Optional host id; defaults to Svelte $props.id(), stable during SSR and hydration. */
|
|
11
11
|
readonly id?: string;
|
|
12
12
|
}
|
package/dist/Typed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typed.d.ts","sourceRoot":"","sources":["../src/Typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,qEAAqE;AACrE,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,KAAK,CAAE,SAAQ,iBAAiB,CACzF,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CACzB;IACC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CACxB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EACrE,EAAE,CACH,CAAC;IACF,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"Typed.d.ts","sourceRoot":"","sources":["../src/Typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,qEAAqE;AACrE,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,KAAK,CAAE,SAAQ,iBAAiB,CACzF,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CACzB;IACC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CACxB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EACrE,EAAE,CACH,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAElB,yFAAyF;IACzF,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
package/dist/Typed.server.js
CHANGED
|
@@ -10,7 +10,7 @@ export default function Typed($$renderer, $$props) {
|
|
|
10
10
|
$$renderer.component(($$renderer) => {
|
|
11
11
|
const componentId = $.props_id($$renderer);
|
|
12
12
|
var $$store_subs;
|
|
13
|
-
let { runtime,
|
|
13
|
+
let { runtime, value, id, onError, onReady, stopPropagation } = $$props;
|
|
14
14
|
const inherited = useRuntime();
|
|
15
15
|
|
|
16
16
|
// $inherited subscribes to the runtime store and follows provider replacements.
|
|
@@ -22,7 +22,7 @@ export default function Typed($$renderer, $$props) {
|
|
|
22
22
|
|
|
23
23
|
const render = $.derived(() => {
|
|
24
24
|
const selected = selectedRuntime();
|
|
25
|
-
const current =
|
|
25
|
+
const current = value;
|
|
26
26
|
|
|
27
27
|
return (root) => attachment(selected, current, {
|
|
28
28
|
stopPropagation: false,
|
|
@@ -52,7 +52,7 @@ export default function Typed($$renderer, $$props) {
|
|
|
52
52
|
initialHtml;
|
|
53
53
|
|
|
54
54
|
var $$promises = $$renderer.run([
|
|
55
|
-
async () => initialHtml = await renderSnapshot(selectedRuntime(),
|
|
55
|
+
async () => initialHtml = await renderSnapshot(selectedRuntime(), value)
|
|
56
56
|
]);
|
|
57
57
|
|
|
58
58
|
$$renderer.push(`<div${$.attr('id', id ?? componentId)} style="display: contents">`);
|
package/dist/ViewOptions.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { RootEventOptions } from "@typed/template/RootEvents";
|
|
2
2
|
/** Svelte mount, hydration and SSR options for one island. */
|
|
3
3
|
export interface ViewOptions {
|
|
4
|
-
/**
|
|
5
|
-
readonly id
|
|
4
|
+
/** Optional host identity override. Generated per render and restored during hydration by default. */
|
|
5
|
+
readonly id?: string;
|
|
6
6
|
/** Per-event bubbling policy at the automatic host. Inherits CurrentRootEvents when omitted. */
|
|
7
7
|
readonly stopPropagation?: RootEventOptions;
|
|
8
8
|
readonly context?: Map<any, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewOptions.d.ts","sourceRoot":"","sources":["../src/ViewOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,
|
|
1
|
+
{"version":3,"file":"ViewOptions.d.ts","sourceRoot":"","sources":["../src/ViewOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,sGAAsG;IACtG,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,QAAQ,CAAC,eAAe,CAAC,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IACtD,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dom.d.ts","sourceRoot":"","sources":["../../src/internal/Dom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAI3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,cAAc,GAAwB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"Dom.d.ts","sourceRoot":"","sources":["../../src/internal/Dom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAI3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,cAAc,GAAwB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,yOAqDnE,CAAC"}
|
package/dist/internal/Dom.js
CHANGED
|
@@ -33,12 +33,9 @@ export const mountComponent = Effect.fn(function* (element, component, props, op
|
|
|
33
33
|
context,
|
|
34
34
|
intro: options.intro,
|
|
35
35
|
transformError: options.transformError,
|
|
36
|
+
recover: options.recover,
|
|
36
37
|
};
|
|
37
|
-
|
|
38
|
-
instance = hydrate
|
|
39
|
-
? hydrateComponent(Bridge, { ...common, recover: options.recover })
|
|
40
|
-
: mount(Bridge, common);
|
|
41
|
-
});
|
|
38
|
+
instance = hydrate ? hydrateComponent(Bridge, common) : mount(Bridge, common);
|
|
42
39
|
// Publication follows native Typed ref timing; Svelte schedules its own commit.
|
|
43
40
|
yield* Deferred.succeed(ready, undefined);
|
|
44
41
|
yield* Effect.promise(tick).pipe(Effect.onExit((exit) => Deferred.done(committed, exit)));
|
package/dist/view.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RandomValues } from "@typed/id/RandomValues";
|
|
1
2
|
import * as Scope from "effect/Scope";
|
|
2
3
|
import * as Fx from "@typed/fx/Fx";
|
|
3
4
|
import { type RenderEvent } from "@typed/template/RenderEvent";
|
|
@@ -7,5 +8,5 @@ import { type Source } from "./Source.js";
|
|
|
7
8
|
import type { ViewOptions } from "./ViewOptions.js";
|
|
8
9
|
export type { ViewOptions } from "./ViewOptions.js";
|
|
9
10
|
/** A native Typed template that mounts or serializes a Svelte component. */
|
|
10
|
-
export declare function view<Props extends Record<string, any>, E = never, R = never>(component: Component<Props>, props: Source<NoInfer<Props>, E, R>, options
|
|
11
|
+
export declare function view<Props extends Record<string, any>, E = never, R = never>(component: Component<Props>, props: Source<NoInfer<Props>, E, R>, options?: ViewOptions): Fx.Fx<RenderEvent, E, R | Scope.Scope | RenderTemplate | RandomValues>;
|
|
11
12
|
//# sourceMappingURL=view.d.ts.map
|
package/dist/view.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,4EAA4E;AAC5E,wBAAgB,IAAI,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,EAC1E,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,EAC3B,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACnC,OAAO,GAAE,WAAgB,GACxB,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,cAAc,GAAG,YAAY,CAAC,CAqExE"}
|
package/dist/view.js
CHANGED
|
@@ -7,15 +7,14 @@ import * as Option from "effect/Option";
|
|
|
7
7
|
import * as Scope from "effect/Scope";
|
|
8
8
|
import * as Fx from "@typed/fx/Fx";
|
|
9
9
|
import { DomRenderEvent, HtmlRenderEvent, isDomRenderEvent, } from "@typed/template/RenderEvent";
|
|
10
|
+
import { rootIdentity } from "@typed/template/RootIdentity";
|
|
10
11
|
import { HydrateContext } from "@typed/template/HydrateContext";
|
|
11
12
|
import { html } from "@typed/template/RenderTemplate";
|
|
12
13
|
import { toFx } from "./Source.js";
|
|
13
14
|
/** A native Typed template that mounts or serializes a Svelte component. */
|
|
14
|
-
export function view(component, props, options) {
|
|
15
|
+
export function view(component, props, options = {}) {
|
|
15
16
|
return Fx.gen(function* () {
|
|
16
|
-
|
|
17
|
-
throw new TypeError("Svelte view requires a nonempty id, unique within the rendered page");
|
|
18
|
-
}
|
|
17
|
+
const identity = yield* rootIdentity(options.id);
|
|
19
18
|
const source = toFx(props);
|
|
20
19
|
const scope = yield* Scope.fork(yield* Effect.scope);
|
|
21
20
|
const ready = yield* Deferred.make();
|
|
@@ -25,9 +24,10 @@ export function view(component, props, options) {
|
|
|
25
24
|
target = element;
|
|
26
25
|
};
|
|
27
26
|
const content = Fx.gen(function* () {
|
|
27
|
+
const settings = { ...options, id: yield* identity.id };
|
|
28
28
|
if (target === undefined) {
|
|
29
29
|
const { render } = yield* Effect.promise(() => import("./internal/Html.js"));
|
|
30
|
-
return Fx.fromEffect(render(component, source,
|
|
30
|
+
return Fx.fromEffect(render(component, source, settings)).pipe(Fx.map((html) => HtmlRenderEvent(html, true)));
|
|
31
31
|
}
|
|
32
32
|
const hydration = yield* Effect.serviceOption(HydrateContext);
|
|
33
33
|
const hydrate = Option.isSome(hydration) && hydration.value.where._tag === "hole";
|
|
@@ -37,10 +37,17 @@ export function view(component, props, options) {
|
|
|
37
37
|
hydration.value.where.endComment.remove();
|
|
38
38
|
}
|
|
39
39
|
const element = target;
|
|
40
|
-
const mount = Effect.promise(() => import("./internal/Dom.js")).pipe(Effect.flatMap(({ mountComponent }) => Layer.launch(mountComponent(element, component, source,
|
|
40
|
+
const mount = Effect.promise(() => import("./internal/Dom.js")).pipe(Effect.flatMap(({ mountComponent }) => Layer.launch(mountComponent(element, component, source, settings, ready, hydrate))), Effect.onExit((exit) => Deferred.done(ready, exit)));
|
|
41
41
|
return Fx.fromEffect(mount).pipe(Fx.prepend(DomRenderEvent([])));
|
|
42
42
|
});
|
|
43
|
-
return html `<div
|
|
43
|
+
return html `<div
|
|
44
|
+
...${{ ref: identity.ref }}
|
|
45
|
+
id=${identity.id}
|
|
46
|
+
style="display: contents"
|
|
47
|
+
ref=${ref}
|
|
48
|
+
>
|
|
49
|
+
${content}
|
|
50
|
+
</div>`.pipe(Fx.provideService(Scope.Scope, scope), Fx.concatMap((event) => isDomRenderEvent(event)
|
|
44
51
|
? Fx.fromEffect(Deferred.await(ready)).pipe(Fx.map(() => {
|
|
45
52
|
published = true;
|
|
46
53
|
return event;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typed/svelte",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.8",
|
|
4
4
|
"description": "Bidirectional Svelte integration for Typed templates.",
|
|
5
|
-
"homepage": "https://github.com/TylorS/typed
|
|
6
|
-
"bugs": "https://github.com/TylorS/typed
|
|
5
|
+
"homepage": "https://github.com/TylorS/typed/tree/development/packages/svelte#readme",
|
|
6
|
+
"bugs": "https://github.com/TylorS/typed/issues",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/TylorS/typed
|
|
10
|
+
"url": "git+https://github.com/TylorS/typed.git",
|
|
11
11
|
"directory": "packages/svelte"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
@@ -66,18 +66,19 @@
|
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@typed/async-data": "1.0.0-beta.
|
|
70
|
-
"@typed/fx": "2.0.0-beta.
|
|
71
|
-
"@typed/
|
|
72
|
-
"@typed/
|
|
73
|
-
"@typed/
|
|
69
|
+
"@typed/async-data": "1.0.0-beta.8",
|
|
70
|
+
"@typed/fx": "2.0.0-beta.8",
|
|
71
|
+
"@typed/id": "1.0.0-beta.8",
|
|
72
|
+
"@typed/navigation": "1.0.0-beta.8",
|
|
73
|
+
"@typed/router": "1.0.0-beta.8",
|
|
74
|
+
"@typed/template": "1.0.0-beta.8",
|
|
74
75
|
"effect": "4.0.0-rc.112"
|
|
75
76
|
},
|
|
76
77
|
"devDependencies": {
|
|
77
78
|
"@sveltejs/vite-plugin-svelte": "7.3.0",
|
|
78
79
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
79
80
|
"@vitest/browser-playwright": "5.0.0",
|
|
80
|
-
"playwright": "^1.
|
|
81
|
+
"playwright": "^1.63.0",
|
|
81
82
|
"svelte": "5.57.0",
|
|
82
83
|
"svelte-check": "4.7.6",
|
|
83
84
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|