sygnal 5.1.1 → 5.1.2
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/README.md +23 -2
- package/dist/astro/client.cjs.js +14 -3
- package/dist/astro/client.mjs +14 -3
- package/dist/astro/cycle/dom/DocumentDOMSource.d.ts +7 -5
- package/dist/astro/cycle/dom/MainDOMSource.d.ts +2 -1
- package/dist/astro/cycle/dom/enrichEventStream.d.ts +24 -0
- package/dist/astro/server.cjs.js +6 -0
- package/dist/astro/server.mjs +6 -0
- package/dist/cycle/dom/DocumentDOMSource.d.ts +7 -5
- package/dist/cycle/dom/MainDOMSource.d.ts +2 -1
- package/dist/cycle/dom/enrichEventStream.d.ts +24 -0
- package/dist/index.cjs.js +20 -3
- package/dist/index.esm.js +20 -3
- package/dist/sygnal.min.js +1 -1
- package/dist/vike/+config.cjs.js +58 -0
- package/dist/vike/+config.js +56 -0
- package/dist/vike/onRenderClient.cjs.js +66 -0
- package/dist/vike/onRenderClient.mjs +64 -0
- package/dist/vike/onRenderHtml.cjs.js +158 -0
- package/dist/vike/onRenderHtml.mjs +156 -0
- package/package.json +24 -1
- package/src/component.ts +14 -3
- package/src/cycle/dom/DocumentDOMSource.ts +5 -5
- package/src/cycle/dom/MainDOMSource.ts +5 -5
- package/src/extra/ssr.ts +7 -0
- package/src/vike/+config.ts +58 -0
- package/src/vike/onRenderClient.ts +84 -0
- package/src/vike/onRenderHtml.ts +175 -0
- package/src/vike/types.ts +29 -0
package/README.md
CHANGED
|
@@ -21,12 +21,13 @@ A reactive component framework with pure functions, zero side effects, and autom
|
|
|
21
21
|
**Scaffold a new project:**
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
|
|
24
|
+
npm create sygnal-app my-app
|
|
25
25
|
cd my-app
|
|
26
|
-
npm install
|
|
27
26
|
npm run dev
|
|
28
27
|
```
|
|
29
28
|
|
|
29
|
+
Choose from Vite (SPA), Vike (SSR), or Astro templates during setup.
|
|
30
|
+
|
|
30
31
|
**Or add to an existing project:**
|
|
31
32
|
|
|
32
33
|
```bash
|
|
@@ -386,6 +387,25 @@ import Counter from '../components/Counter.jsx'
|
|
|
386
387
|
<Counter client:load />
|
|
387
388
|
```
|
|
388
389
|
|
|
390
|
+
### Vike Integration
|
|
391
|
+
|
|
392
|
+
File-based routing with SSR, client-side navigation, and automatic hydration:
|
|
393
|
+
|
|
394
|
+
```javascript
|
|
395
|
+
// vite.config.js
|
|
396
|
+
import sygnal from 'sygnal/vite'
|
|
397
|
+
import vike from 'vike/plugin'
|
|
398
|
+
export default defineConfig({ plugins: [sygnal({ disableHmr: true }), vike()] })
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
// pages/+config.js
|
|
403
|
+
import vikeSygnal from 'sygnal/config'
|
|
404
|
+
export default { extends: [vikeSygnal] }
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Pages are standard Sygnal components in `pages/*/+Page.jsx`. Supports layouts, data fetching, and SPA mode.
|
|
408
|
+
|
|
389
409
|
### TypeScript
|
|
390
410
|
|
|
391
411
|
Full type definitions included:
|
|
@@ -443,6 +463,7 @@ h('div', [h('h1', 'Hello'), h('button.btn', 'Click')])
|
|
|
443
463
|
|---------|-------------|
|
|
444
464
|
| [Getting Started](./examples/getting-started) | Interactive guide with live demos (Astro) |
|
|
445
465
|
| [Kanban Board](./examples/kanban) | Drag-and-drop with Collections and cross-component communication |
|
|
466
|
+
| [Vike SSR](./examples/vike) | File-based routing with SSR, layouts, and data fetching |
|
|
446
467
|
| [Advanced Features](./examples/advanced-feature-tests) | Portals, slots, disposal, suspense, lazy loading |
|
|
447
468
|
| [TypeScript 2048](./examples/ts-example-2048) | Full game in TypeScript |
|
|
448
469
|
| [AI Discussion Panel](./examples/ai-panel-spa) | Complex SPA with custom drivers |
|
package/dist/astro/client.cjs.js
CHANGED
|
@@ -5462,7 +5462,18 @@ function wrapDOMSource(domSource) {
|
|
|
5462
5462
|
}
|
|
5463
5463
|
});
|
|
5464
5464
|
}
|
|
5465
|
-
const ABORT = Symbol('ABORT');
|
|
5465
|
+
const ABORT = Symbol.for('sygnal.ABORT');
|
|
5466
|
+
/**
|
|
5467
|
+
* Check if a value is the ABORT sentinel.
|
|
5468
|
+
* Uses Symbol.for() identity first, then falls back to description check
|
|
5469
|
+
* in case bundlers (e.g. Vite) create duplicate module instances with
|
|
5470
|
+
* separate Symbol.for() registries.
|
|
5471
|
+
*/
|
|
5472
|
+
function isAbort(value) {
|
|
5473
|
+
if (value === ABORT)
|
|
5474
|
+
return true;
|
|
5475
|
+
return typeof value === 'symbol' && value.description === 'sygnal.ABORT';
|
|
5476
|
+
}
|
|
5466
5477
|
function normalizeCalculatedEntry(field, entry) {
|
|
5467
5478
|
if (typeof entry === 'function') {
|
|
5468
5479
|
return { fn: entry, deps: null };
|
|
@@ -6184,7 +6195,7 @@ class Component {
|
|
|
6184
6195
|
const enhancedState = this.addCalculated(_state);
|
|
6185
6196
|
props.state = enhancedState;
|
|
6186
6197
|
const newState = reducer(enhancedState, data, next, props);
|
|
6187
|
-
if (newState
|
|
6198
|
+
if (isAbort(newState))
|
|
6188
6199
|
return _state;
|
|
6189
6200
|
return this.cleanupCalculated(newState);
|
|
6190
6201
|
}
|
|
@@ -6213,7 +6224,7 @@ class Component {
|
|
|
6213
6224
|
return ABORT;
|
|
6214
6225
|
}
|
|
6215
6226
|
}
|
|
6216
|
-
}).filter((result) => result
|
|
6227
|
+
}).filter((result) => !isAbort(result));
|
|
6217
6228
|
}
|
|
6218
6229
|
else if (reducer === undefined || reducer === true) {
|
|
6219
6230
|
returnStream$ = filtered$.map(({ data }) => data);
|
package/dist/astro/client.mjs
CHANGED
|
@@ -5460,7 +5460,18 @@ function wrapDOMSource(domSource) {
|
|
|
5460
5460
|
}
|
|
5461
5461
|
});
|
|
5462
5462
|
}
|
|
5463
|
-
const ABORT = Symbol('ABORT');
|
|
5463
|
+
const ABORT = Symbol.for('sygnal.ABORT');
|
|
5464
|
+
/**
|
|
5465
|
+
* Check if a value is the ABORT sentinel.
|
|
5466
|
+
* Uses Symbol.for() identity first, then falls back to description check
|
|
5467
|
+
* in case bundlers (e.g. Vite) create duplicate module instances with
|
|
5468
|
+
* separate Symbol.for() registries.
|
|
5469
|
+
*/
|
|
5470
|
+
function isAbort(value) {
|
|
5471
|
+
if (value === ABORT)
|
|
5472
|
+
return true;
|
|
5473
|
+
return typeof value === 'symbol' && value.description === 'sygnal.ABORT';
|
|
5474
|
+
}
|
|
5464
5475
|
function normalizeCalculatedEntry(field, entry) {
|
|
5465
5476
|
if (typeof entry === 'function') {
|
|
5466
5477
|
return { fn: entry, deps: null };
|
|
@@ -6182,7 +6193,7 @@ class Component {
|
|
|
6182
6193
|
const enhancedState = this.addCalculated(_state);
|
|
6183
6194
|
props.state = enhancedState;
|
|
6184
6195
|
const newState = reducer(enhancedState, data, next, props);
|
|
6185
|
-
if (newState
|
|
6196
|
+
if (isAbort(newState))
|
|
6186
6197
|
return _state;
|
|
6187
6198
|
return this.cleanupCalculated(newState);
|
|
6188
6199
|
}
|
|
@@ -6211,7 +6222,7 @@ class Component {
|
|
|
6211
6222
|
return ABORT;
|
|
6212
6223
|
}
|
|
6213
6224
|
}
|
|
6214
|
-
}).filter((result) => result
|
|
6225
|
+
}).filter((result) => !isAbort(result));
|
|
6215
6226
|
}
|
|
6216
6227
|
else if (reducer === undefined || reducer === true) {
|
|
6217
6228
|
returnStream$ = filtered$.map(({ data }) => data);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MemoryStream } from 'xstream';
|
|
2
2
|
import { EventsFnOptions } from './DOMSource';
|
|
3
|
+
import { EnrichedEventStream } from './enrichEventStream';
|
|
3
4
|
export declare class DocumentDOMSource {
|
|
4
5
|
private _name;
|
|
5
|
-
|
|
6
|
+
private _selector;
|
|
7
|
+
constructor(_name: string, selector?: string);
|
|
6
8
|
select(selector: string): DocumentDOMSource;
|
|
7
|
-
elements(): MemoryStream<Array<Document>>;
|
|
8
|
-
element(): MemoryStream<Document>;
|
|
9
|
-
events<K extends keyof DocumentEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean):
|
|
9
|
+
elements(): MemoryStream<Array<Document | Element>>;
|
|
10
|
+
element(): MemoryStream<Document | Element | null>;
|
|
11
|
+
events<K extends keyof DocumentEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): EnrichedEventStream<DocumentEventMap[K]>;
|
|
10
12
|
}
|
|
@@ -3,6 +3,7 @@ import { EventsFnOptions } from './DOMSource';
|
|
|
3
3
|
import { DocumentDOMSource } from './DocumentDOMSource';
|
|
4
4
|
import { BodyDOMSource } from './BodyDOMSource';
|
|
5
5
|
import { VNode } from './snabbdom';
|
|
6
|
+
import { EnrichedEventStream } from './enrichEventStream';
|
|
6
7
|
import { Scope, IsolateSink } from './isolate';
|
|
7
8
|
import { IsolateModule } from './IsolateModule';
|
|
8
9
|
import { EventDelegator } from './EventDelegator';
|
|
@@ -24,7 +25,7 @@ export declare class MainDOMSource {
|
|
|
24
25
|
get namespace(): Array<Scope>;
|
|
25
26
|
select<T extends keyof SpecialSelector>(selector: T): SpecialSelector[T];
|
|
26
27
|
select(selector: string): MainDOMSource;
|
|
27
|
-
events<K extends keyof HTMLElementEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean):
|
|
28
|
+
events<K extends keyof HTMLElementEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): EnrichedEventStream<HTMLElementEventMap[K]>;
|
|
28
29
|
dispose(): void;
|
|
29
30
|
isolateSource: (source: MainDOMSource, scope: string) => MainDOMSource;
|
|
30
31
|
isolateSink: IsolateSink<VNode>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Stream } from 'xstream';
|
|
2
|
+
export interface EnrichedEventStream<T = Event> extends Stream<T> {
|
|
3
|
+
value(): EnrichedEventStream<string>;
|
|
4
|
+
value<R>(fn: (val: string) => R): EnrichedEventStream<R>;
|
|
5
|
+
checked(): EnrichedEventStream<boolean>;
|
|
6
|
+
checked<R>(fn: (val: boolean) => R): EnrichedEventStream<R>;
|
|
7
|
+
data(name: string): EnrichedEventStream<string | undefined>;
|
|
8
|
+
data<R>(name: string, fn: (val: string | undefined) => R): EnrichedEventStream<R>;
|
|
9
|
+
target(): EnrichedEventStream<EventTarget | null>;
|
|
10
|
+
target<R>(fn: (el: EventTarget | null) => R): EnrichedEventStream<R>;
|
|
11
|
+
key(): EnrichedEventStream<string>;
|
|
12
|
+
key<R>(fn: (key: string) => R): EnrichedEventStream<R>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Adds chainable convenience methods to a DOM event stream.
|
|
16
|
+
*
|
|
17
|
+
* DOM.select('.input').events('input').value()
|
|
18
|
+
* DOM.input('.input').value()
|
|
19
|
+
* DOM.select('.item').events('click').data('id')
|
|
20
|
+
* DOM.click('.item').data('id', Number)
|
|
21
|
+
* DOM.change('.checkbox').checked()
|
|
22
|
+
* DOM.keydown('.field').key()
|
|
23
|
+
*/
|
|
24
|
+
export declare function enrichEventStream(stream$: any): any;
|
package/dist/astro/server.cjs.js
CHANGED
|
@@ -514,6 +514,12 @@ function vnodeToHtml(vnode) {
|
|
|
514
514
|
if (VOID_ELEMENTS.has(tag)) {
|
|
515
515
|
return html;
|
|
516
516
|
}
|
|
517
|
+
// If innerHTML is set via props, use it as raw content (no escaping)
|
|
518
|
+
if (vnode.data?.props?.innerHTML != null) {
|
|
519
|
+
html += String(vnode.data.props.innerHTML);
|
|
520
|
+
html += `</${tag}>`;
|
|
521
|
+
return html;
|
|
522
|
+
}
|
|
517
523
|
// Children — snabbdom uses `text` for single text children (even when
|
|
518
524
|
// `children` holds a text element object). Prioritize `text` when set.
|
|
519
525
|
if (vnode.text != null) {
|
package/dist/astro/server.mjs
CHANGED
|
@@ -510,6 +510,12 @@ function vnodeToHtml(vnode) {
|
|
|
510
510
|
if (VOID_ELEMENTS.has(tag)) {
|
|
511
511
|
return html;
|
|
512
512
|
}
|
|
513
|
+
// If innerHTML is set via props, use it as raw content (no escaping)
|
|
514
|
+
if (vnode.data?.props?.innerHTML != null) {
|
|
515
|
+
html += String(vnode.data.props.innerHTML);
|
|
516
|
+
html += `</${tag}>`;
|
|
517
|
+
return html;
|
|
518
|
+
}
|
|
513
519
|
// Children — snabbdom uses `text` for single text children (even when
|
|
514
520
|
// `children` holds a text element object). Prioritize `text` when set.
|
|
515
521
|
if (vnode.text != null) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MemoryStream } from 'xstream';
|
|
2
2
|
import { EventsFnOptions } from './DOMSource';
|
|
3
|
+
import { EnrichedEventStream } from './enrichEventStream';
|
|
3
4
|
export declare class DocumentDOMSource {
|
|
4
5
|
private _name;
|
|
5
|
-
|
|
6
|
+
private _selector;
|
|
7
|
+
constructor(_name: string, selector?: string);
|
|
6
8
|
select(selector: string): DocumentDOMSource;
|
|
7
|
-
elements(): MemoryStream<Array<Document>>;
|
|
8
|
-
element(): MemoryStream<Document>;
|
|
9
|
-
events<K extends keyof DocumentEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean):
|
|
9
|
+
elements(): MemoryStream<Array<Document | Element>>;
|
|
10
|
+
element(): MemoryStream<Document | Element | null>;
|
|
11
|
+
events<K extends keyof DocumentEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): EnrichedEventStream<DocumentEventMap[K]>;
|
|
10
12
|
}
|
|
@@ -3,6 +3,7 @@ import { EventsFnOptions } from './DOMSource';
|
|
|
3
3
|
import { DocumentDOMSource } from './DocumentDOMSource';
|
|
4
4
|
import { BodyDOMSource } from './BodyDOMSource';
|
|
5
5
|
import { VNode } from './snabbdom';
|
|
6
|
+
import { EnrichedEventStream } from './enrichEventStream';
|
|
6
7
|
import { Scope, IsolateSink } from './isolate';
|
|
7
8
|
import { IsolateModule } from './IsolateModule';
|
|
8
9
|
import { EventDelegator } from './EventDelegator';
|
|
@@ -24,7 +25,7 @@ export declare class MainDOMSource {
|
|
|
24
25
|
get namespace(): Array<Scope>;
|
|
25
26
|
select<T extends keyof SpecialSelector>(selector: T): SpecialSelector[T];
|
|
26
27
|
select(selector: string): MainDOMSource;
|
|
27
|
-
events<K extends keyof HTMLElementEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean):
|
|
28
|
+
events<K extends keyof HTMLElementEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): EnrichedEventStream<HTMLElementEventMap[K]>;
|
|
28
29
|
dispose(): void;
|
|
29
30
|
isolateSource: (source: MainDOMSource, scope: string) => MainDOMSource;
|
|
30
31
|
isolateSink: IsolateSink<VNode>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Stream } from 'xstream';
|
|
2
|
+
export interface EnrichedEventStream<T = Event> extends Stream<T> {
|
|
3
|
+
value(): EnrichedEventStream<string>;
|
|
4
|
+
value<R>(fn: (val: string) => R): EnrichedEventStream<R>;
|
|
5
|
+
checked(): EnrichedEventStream<boolean>;
|
|
6
|
+
checked<R>(fn: (val: boolean) => R): EnrichedEventStream<R>;
|
|
7
|
+
data(name: string): EnrichedEventStream<string | undefined>;
|
|
8
|
+
data<R>(name: string, fn: (val: string | undefined) => R): EnrichedEventStream<R>;
|
|
9
|
+
target(): EnrichedEventStream<EventTarget | null>;
|
|
10
|
+
target<R>(fn: (el: EventTarget | null) => R): EnrichedEventStream<R>;
|
|
11
|
+
key(): EnrichedEventStream<string>;
|
|
12
|
+
key<R>(fn: (key: string) => R): EnrichedEventStream<R>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Adds chainable convenience methods to a DOM event stream.
|
|
16
|
+
*
|
|
17
|
+
* DOM.select('.input').events('input').value()
|
|
18
|
+
* DOM.input('.input').value()
|
|
19
|
+
* DOM.select('.item').events('click').data('id')
|
|
20
|
+
* DOM.click('.item').data('id', Number)
|
|
21
|
+
* DOM.change('.checkbox').checked()
|
|
22
|
+
* DOM.keydown('.field').key()
|
|
23
|
+
*/
|
|
24
|
+
export declare function enrichEventStream(stream$: any): any;
|
package/dist/index.cjs.js
CHANGED
|
@@ -2205,7 +2205,18 @@ function wrapDOMSource(domSource) {
|
|
|
2205
2205
|
}
|
|
2206
2206
|
});
|
|
2207
2207
|
}
|
|
2208
|
-
const ABORT = Symbol('ABORT');
|
|
2208
|
+
const ABORT = Symbol.for('sygnal.ABORT');
|
|
2209
|
+
/**
|
|
2210
|
+
* Check if a value is the ABORT sentinel.
|
|
2211
|
+
* Uses Symbol.for() identity first, then falls back to description check
|
|
2212
|
+
* in case bundlers (e.g. Vite) create duplicate module instances with
|
|
2213
|
+
* separate Symbol.for() registries.
|
|
2214
|
+
*/
|
|
2215
|
+
function isAbort(value) {
|
|
2216
|
+
if (value === ABORT)
|
|
2217
|
+
return true;
|
|
2218
|
+
return typeof value === 'symbol' && value.description === 'sygnal.ABORT';
|
|
2219
|
+
}
|
|
2209
2220
|
function normalizeCalculatedEntry(field, entry) {
|
|
2210
2221
|
if (typeof entry === 'function') {
|
|
2211
2222
|
return { fn: entry, deps: null };
|
|
@@ -2927,7 +2938,7 @@ class Component {
|
|
|
2927
2938
|
const enhancedState = this.addCalculated(_state);
|
|
2928
2939
|
props.state = enhancedState;
|
|
2929
2940
|
const newState = reducer(enhancedState, data, next, props);
|
|
2930
|
-
if (newState
|
|
2941
|
+
if (isAbort(newState))
|
|
2931
2942
|
return _state;
|
|
2932
2943
|
return this.cleanupCalculated(newState);
|
|
2933
2944
|
}
|
|
@@ -2956,7 +2967,7 @@ class Component {
|
|
|
2956
2967
|
return ABORT;
|
|
2957
2968
|
}
|
|
2958
2969
|
}
|
|
2959
|
-
}).filter((result) => result
|
|
2970
|
+
}).filter((result) => !isAbort(result));
|
|
2960
2971
|
}
|
|
2961
2972
|
else if (reducer === undefined || reducer === true) {
|
|
2962
2973
|
returnStream$ = filtered$.map(({ data }) => data);
|
|
@@ -6326,6 +6337,12 @@ function vnodeToHtml(vnode) {
|
|
|
6326
6337
|
if (VOID_ELEMENTS.has(tag)) {
|
|
6327
6338
|
return html;
|
|
6328
6339
|
}
|
|
6340
|
+
// If innerHTML is set via props, use it as raw content (no escaping)
|
|
6341
|
+
if (vnode.data?.props?.innerHTML != null) {
|
|
6342
|
+
html += String(vnode.data.props.innerHTML);
|
|
6343
|
+
html += `</${tag}>`;
|
|
6344
|
+
return html;
|
|
6345
|
+
}
|
|
6329
6346
|
// Children — snabbdom uses `text` for single text children (even when
|
|
6330
6347
|
// `children` holds a text element object). Prioritize `text` when set.
|
|
6331
6348
|
if (vnode.text != null) {
|
package/dist/index.esm.js
CHANGED
|
@@ -2184,7 +2184,18 @@ function wrapDOMSource(domSource) {
|
|
|
2184
2184
|
}
|
|
2185
2185
|
});
|
|
2186
2186
|
}
|
|
2187
|
-
const ABORT = Symbol('ABORT');
|
|
2187
|
+
const ABORT = Symbol.for('sygnal.ABORT');
|
|
2188
|
+
/**
|
|
2189
|
+
* Check if a value is the ABORT sentinel.
|
|
2190
|
+
* Uses Symbol.for() identity first, then falls back to description check
|
|
2191
|
+
* in case bundlers (e.g. Vite) create duplicate module instances with
|
|
2192
|
+
* separate Symbol.for() registries.
|
|
2193
|
+
*/
|
|
2194
|
+
function isAbort(value) {
|
|
2195
|
+
if (value === ABORT)
|
|
2196
|
+
return true;
|
|
2197
|
+
return typeof value === 'symbol' && value.description === 'sygnal.ABORT';
|
|
2198
|
+
}
|
|
2188
2199
|
function normalizeCalculatedEntry(field, entry) {
|
|
2189
2200
|
if (typeof entry === 'function') {
|
|
2190
2201
|
return { fn: entry, deps: null };
|
|
@@ -2906,7 +2917,7 @@ class Component {
|
|
|
2906
2917
|
const enhancedState = this.addCalculated(_state);
|
|
2907
2918
|
props.state = enhancedState;
|
|
2908
2919
|
const newState = reducer(enhancedState, data, next, props);
|
|
2909
|
-
if (newState
|
|
2920
|
+
if (isAbort(newState))
|
|
2910
2921
|
return _state;
|
|
2911
2922
|
return this.cleanupCalculated(newState);
|
|
2912
2923
|
}
|
|
@@ -2935,7 +2946,7 @@ class Component {
|
|
|
2935
2946
|
return ABORT;
|
|
2936
2947
|
}
|
|
2937
2948
|
}
|
|
2938
|
-
}).filter((result) => result
|
|
2949
|
+
}).filter((result) => !isAbort(result));
|
|
2939
2950
|
}
|
|
2940
2951
|
else if (reducer === undefined || reducer === true) {
|
|
2941
2952
|
returnStream$ = filtered$.map(({ data }) => data);
|
|
@@ -6305,6 +6316,12 @@ function vnodeToHtml(vnode) {
|
|
|
6305
6316
|
if (VOID_ELEMENTS.has(tag)) {
|
|
6306
6317
|
return html;
|
|
6307
6318
|
}
|
|
6319
|
+
// If innerHTML is set via props, use it as raw content (no escaping)
|
|
6320
|
+
if (vnode.data?.props?.innerHTML != null) {
|
|
6321
|
+
html += String(vnode.data.props.innerHTML);
|
|
6322
|
+
html += `</${tag}>`;
|
|
6323
|
+
return html;
|
|
6324
|
+
}
|
|
6308
6325
|
// Children — snabbdom uses `text` for single text children (even when
|
|
6309
6326
|
// `children` holds a text element object). Prioritize `text` when set.
|
|
6310
6327
|
if (vnode.text != null) {
|