sygnal 5.1.0 → 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 +29 -4
- package/dist/astro/client.mjs +29 -4
- 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 +36 -5
- package/dist/index.esm.js +36 -5
- package/dist/jsx-dev-runtime.cjs.js +17 -2
- package/dist/jsx-dev-runtime.esm.js +17 -2
- package/dist/jsx-runtime.cjs.js +17 -2
- package/dist/jsx-runtime.esm.js +17 -2
- package/dist/jsx.cjs.js +1 -1
- package/dist/jsx.esm.js +1 -1
- 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/cycle/dom/snabbdom.ts +5 -1
- package/src/extra/ssr.ts +7 -0
- package/src/pragma/index.ts +1 -1
- 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
|
@@ -4,7 +4,7 @@ var h = require('snabbdom/build/h');
|
|
|
4
4
|
var init = require('snabbdom/build/init');
|
|
5
5
|
var tovnode = require('snabbdom/build/tovnode');
|
|
6
6
|
var vnode = require('snabbdom/build/vnode');
|
|
7
|
-
require('snabbdom/build/jsx');
|
|
7
|
+
var jsx = require('snabbdom/build/jsx');
|
|
8
8
|
var _class = require('snabbdom/build/modules/class');
|
|
9
9
|
var props = require('snabbdom/build/modules/props');
|
|
10
10
|
var attributes = require('snabbdom/build/modules/attributes');
|
|
@@ -3570,6 +3570,20 @@ function withState(main, name = 'state') {
|
|
|
3570
3570
|
};
|
|
3571
3571
|
}
|
|
3572
3572
|
|
|
3573
|
+
/**
|
|
3574
|
+
* Local snabbdom re-export barrel.
|
|
3575
|
+
*
|
|
3576
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
3577
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
3578
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
3579
|
+
*
|
|
3580
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
3581
|
+
* window guard.
|
|
3582
|
+
*/
|
|
3583
|
+
// Core
|
|
3584
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
3585
|
+
jsx.Fragment.__sygnalFragment = true;
|
|
3586
|
+
|
|
3573
3587
|
function fromEvent(element, eventName, useCapture = false, preventDefault = false, passive = false) {
|
|
3574
3588
|
let next = null;
|
|
3575
3589
|
return Stream_1.create({
|
|
@@ -5448,7 +5462,18 @@ function wrapDOMSource(domSource) {
|
|
|
5448
5462
|
}
|
|
5449
5463
|
});
|
|
5450
5464
|
}
|
|
5451
|
-
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
|
+
}
|
|
5452
5477
|
function normalizeCalculatedEntry(field, entry) {
|
|
5453
5478
|
if (typeof entry === 'function') {
|
|
5454
5479
|
return { fn: entry, deps: null };
|
|
@@ -6170,7 +6195,7 @@ class Component {
|
|
|
6170
6195
|
const enhancedState = this.addCalculated(_state);
|
|
6171
6196
|
props.state = enhancedState;
|
|
6172
6197
|
const newState = reducer(enhancedState, data, next, props);
|
|
6173
|
-
if (newState
|
|
6198
|
+
if (isAbort(newState))
|
|
6174
6199
|
return _state;
|
|
6175
6200
|
return this.cleanupCalculated(newState);
|
|
6176
6201
|
}
|
|
@@ -6199,7 +6224,7 @@ class Component {
|
|
|
6199
6224
|
return ABORT;
|
|
6200
6225
|
}
|
|
6201
6226
|
}
|
|
6202
|
-
}).filter((result) => result
|
|
6227
|
+
}).filter((result) => !isAbort(result));
|
|
6203
6228
|
}
|
|
6204
6229
|
else if (reducer === undefined || reducer === true) {
|
|
6205
6230
|
returnStream$ = filtered$.map(({ data }) => data);
|
package/dist/astro/client.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { h } from 'snabbdom/build/h';
|
|
|
2
2
|
import { init } from 'snabbdom/build/init';
|
|
3
3
|
import { toVNode } from 'snabbdom/build/tovnode';
|
|
4
4
|
import { vnode } from 'snabbdom/build/vnode';
|
|
5
|
-
import 'snabbdom/build/jsx';
|
|
5
|
+
import { Fragment } from 'snabbdom/build/jsx';
|
|
6
6
|
import { classModule } from 'snabbdom/build/modules/class';
|
|
7
7
|
import { propsModule } from 'snabbdom/build/modules/props';
|
|
8
8
|
import { attributesModule } from 'snabbdom/build/modules/attributes';
|
|
@@ -3568,6 +3568,20 @@ function withState(main, name = 'state') {
|
|
|
3568
3568
|
};
|
|
3569
3569
|
}
|
|
3570
3570
|
|
|
3571
|
+
/**
|
|
3572
|
+
* Local snabbdom re-export barrel.
|
|
3573
|
+
*
|
|
3574
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
3575
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
3576
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
3577
|
+
*
|
|
3578
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
3579
|
+
* window guard.
|
|
3580
|
+
*/
|
|
3581
|
+
// Core
|
|
3582
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
3583
|
+
Fragment.__sygnalFragment = true;
|
|
3584
|
+
|
|
3571
3585
|
function fromEvent(element, eventName, useCapture = false, preventDefault = false, passive = false) {
|
|
3572
3586
|
let next = null;
|
|
3573
3587
|
return Stream_1.create({
|
|
@@ -5446,7 +5460,18 @@ function wrapDOMSource(domSource) {
|
|
|
5446
5460
|
}
|
|
5447
5461
|
});
|
|
5448
5462
|
}
|
|
5449
|
-
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
|
+
}
|
|
5450
5475
|
function normalizeCalculatedEntry(field, entry) {
|
|
5451
5476
|
if (typeof entry === 'function') {
|
|
5452
5477
|
return { fn: entry, deps: null };
|
|
@@ -6168,7 +6193,7 @@ class Component {
|
|
|
6168
6193
|
const enhancedState = this.addCalculated(_state);
|
|
6169
6194
|
props.state = enhancedState;
|
|
6170
6195
|
const newState = reducer(enhancedState, data, next, props);
|
|
6171
|
-
if (newState
|
|
6196
|
+
if (isAbort(newState))
|
|
6172
6197
|
return _state;
|
|
6173
6198
|
return this.cleanupCalculated(newState);
|
|
6174
6199
|
}
|
|
@@ -6197,7 +6222,7 @@ class Component {
|
|
|
6197
6222
|
return ABORT;
|
|
6198
6223
|
}
|
|
6199
6224
|
}
|
|
6200
|
-
}).filter((result) => result
|
|
6225
|
+
}).filter((result) => !isAbort(result));
|
|
6201
6226
|
}
|
|
6202
6227
|
else if (reducer === undefined || reducer === true) {
|
|
6203
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
|
@@ -7,7 +7,7 @@ var h = require('snabbdom/build/h');
|
|
|
7
7
|
var init$1 = require('snabbdom/build/init');
|
|
8
8
|
var tovnode = require('snabbdom/build/tovnode');
|
|
9
9
|
var vnode$1 = require('snabbdom/build/vnode');
|
|
10
|
-
require('snabbdom/build/jsx');
|
|
10
|
+
var jsx = require('snabbdom/build/jsx');
|
|
11
11
|
var _class = require('snabbdom/build/modules/class');
|
|
12
12
|
var props = require('snabbdom/build/modules/props');
|
|
13
13
|
var attributes = require('snabbdom/build/modules/attributes');
|
|
@@ -624,6 +624,20 @@ function withState(main, name = 'state') {
|
|
|
624
624
|
};
|
|
625
625
|
}
|
|
626
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Local snabbdom re-export barrel.
|
|
629
|
+
*
|
|
630
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
631
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
632
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
633
|
+
*
|
|
634
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
635
|
+
* window guard.
|
|
636
|
+
*/
|
|
637
|
+
// Core
|
|
638
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
639
|
+
jsx.Fragment.__sygnalFragment = true;
|
|
640
|
+
|
|
627
641
|
function copyToThunk(vnode, thunkVNode) {
|
|
628
642
|
thunkVNode.elm = vnode.elm;
|
|
629
643
|
vnode.data.fn = thunkVNode.data.fn;
|
|
@@ -2191,7 +2205,18 @@ function wrapDOMSource(domSource) {
|
|
|
2191
2205
|
}
|
|
2192
2206
|
});
|
|
2193
2207
|
}
|
|
2194
|
-
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
|
+
}
|
|
2195
2220
|
function normalizeCalculatedEntry(field, entry) {
|
|
2196
2221
|
if (typeof entry === 'function') {
|
|
2197
2222
|
return { fn: entry, deps: null };
|
|
@@ -2913,7 +2938,7 @@ class Component {
|
|
|
2913
2938
|
const enhancedState = this.addCalculated(_state);
|
|
2914
2939
|
props.state = enhancedState;
|
|
2915
2940
|
const newState = reducer(enhancedState, data, next, props);
|
|
2916
|
-
if (newState
|
|
2941
|
+
if (isAbort(newState))
|
|
2917
2942
|
return _state;
|
|
2918
2943
|
return this.cleanupCalculated(newState);
|
|
2919
2944
|
}
|
|
@@ -2942,7 +2967,7 @@ class Component {
|
|
|
2942
2967
|
return ABORT;
|
|
2943
2968
|
}
|
|
2944
2969
|
}
|
|
2945
|
-
}).filter((result) => result
|
|
2970
|
+
}).filter((result) => !isAbort(result));
|
|
2946
2971
|
}
|
|
2947
2972
|
else if (reducer === undefined || reducer === true) {
|
|
2948
2973
|
returnStream$ = filtered$.map(({ data }) => data);
|
|
@@ -5536,7 +5561,7 @@ const createElementWithModules = (modules) => {
|
|
|
5536
5561
|
console.error('JSX Error: Capitalized HTML element without corresponding factory function. Components with names where the first letter is capital MUST be defined or included at the parent component\'s file scope.');
|
|
5537
5562
|
}
|
|
5538
5563
|
if (fun(sel)) {
|
|
5539
|
-
if (sel.name === 'Fragment') {
|
|
5564
|
+
if (sel.__sygnalFragment || sel.name === 'Fragment') {
|
|
5540
5565
|
return sel(data || {}, children);
|
|
5541
5566
|
}
|
|
5542
5567
|
data || (data = {});
|
|
@@ -6312,6 +6337,12 @@ function vnodeToHtml(vnode) {
|
|
|
6312
6337
|
if (VOID_ELEMENTS.has(tag)) {
|
|
6313
6338
|
return html;
|
|
6314
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
|
+
}
|
|
6315
6346
|
// Children — snabbdom uses `text` for single text children (even when
|
|
6316
6347
|
// `children` holds a text element object). Prioritize `text` when set.
|
|
6317
6348
|
if (vnode.text != null) {
|
package/dist/index.esm.js
CHANGED
|
@@ -9,7 +9,7 @@ export { h } from 'snabbdom/build/h';
|
|
|
9
9
|
import { init as init$1 } from 'snabbdom/build/init';
|
|
10
10
|
import { toVNode } from 'snabbdom/build/tovnode';
|
|
11
11
|
import { vnode as vnode$1 } from 'snabbdom/build/vnode';
|
|
12
|
-
import 'snabbdom/build/jsx';
|
|
12
|
+
import { Fragment } from 'snabbdom/build/jsx';
|
|
13
13
|
import { classModule } from 'snabbdom/build/modules/class';
|
|
14
14
|
import { propsModule } from 'snabbdom/build/modules/props';
|
|
15
15
|
import { attributesModule } from 'snabbdom/build/modules/attributes';
|
|
@@ -603,6 +603,20 @@ function withState(main, name = 'state') {
|
|
|
603
603
|
};
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
+
/**
|
|
607
|
+
* Local snabbdom re-export barrel.
|
|
608
|
+
*
|
|
609
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
610
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
611
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
612
|
+
*
|
|
613
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
614
|
+
* window guard.
|
|
615
|
+
*/
|
|
616
|
+
// Core
|
|
617
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
618
|
+
Fragment.__sygnalFragment = true;
|
|
619
|
+
|
|
606
620
|
function copyToThunk(vnode, thunkVNode) {
|
|
607
621
|
thunkVNode.elm = vnode.elm;
|
|
608
622
|
vnode.data.fn = thunkVNode.data.fn;
|
|
@@ -2170,7 +2184,18 @@ function wrapDOMSource(domSource) {
|
|
|
2170
2184
|
}
|
|
2171
2185
|
});
|
|
2172
2186
|
}
|
|
2173
|
-
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
|
+
}
|
|
2174
2199
|
function normalizeCalculatedEntry(field, entry) {
|
|
2175
2200
|
if (typeof entry === 'function') {
|
|
2176
2201
|
return { fn: entry, deps: null };
|
|
@@ -2892,7 +2917,7 @@ class Component {
|
|
|
2892
2917
|
const enhancedState = this.addCalculated(_state);
|
|
2893
2918
|
props.state = enhancedState;
|
|
2894
2919
|
const newState = reducer(enhancedState, data, next, props);
|
|
2895
|
-
if (newState
|
|
2920
|
+
if (isAbort(newState))
|
|
2896
2921
|
return _state;
|
|
2897
2922
|
return this.cleanupCalculated(newState);
|
|
2898
2923
|
}
|
|
@@ -2921,7 +2946,7 @@ class Component {
|
|
|
2921
2946
|
return ABORT;
|
|
2922
2947
|
}
|
|
2923
2948
|
}
|
|
2924
|
-
}).filter((result) => result
|
|
2949
|
+
}).filter((result) => !isAbort(result));
|
|
2925
2950
|
}
|
|
2926
2951
|
else if (reducer === undefined || reducer === true) {
|
|
2927
2952
|
returnStream$ = filtered$.map(({ data }) => data);
|
|
@@ -5515,7 +5540,7 @@ const createElementWithModules = (modules) => {
|
|
|
5515
5540
|
console.error('JSX Error: Capitalized HTML element without corresponding factory function. Components with names where the first letter is capital MUST be defined or included at the parent component\'s file scope.');
|
|
5516
5541
|
}
|
|
5517
5542
|
if (fun(sel)) {
|
|
5518
|
-
if (sel.name === 'Fragment') {
|
|
5543
|
+
if (sel.__sygnalFragment || sel.name === 'Fragment') {
|
|
5519
5544
|
return sel(data || {}, children);
|
|
5520
5545
|
}
|
|
5521
5546
|
data || (data = {});
|
|
@@ -6291,6 +6316,12 @@ function vnodeToHtml(vnode) {
|
|
|
6291
6316
|
if (VOID_ELEMENTS.has(tag)) {
|
|
6292
6317
|
return html;
|
|
6293
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
|
+
}
|
|
6294
6325
|
// Children — snabbdom uses `text` for single text children (even when
|
|
6295
6326
|
// `children` holds a text element object). Prioritize `text` when set.
|
|
6296
6327
|
if (vnode.text != null) {
|
|
@@ -227,7 +227,7 @@ const createElementWithModules = (modules) => {
|
|
|
227
227
|
console.error('JSX Error: Capitalized HTML element without corresponding factory function. Components with names where the first letter is capital MUST be defined or included at the parent component\'s file scope.');
|
|
228
228
|
}
|
|
229
229
|
if (fun(sel)) {
|
|
230
|
-
if (sel.name === 'Fragment') {
|
|
230
|
+
if (sel.__sygnalFragment || sel.name === 'Fragment') {
|
|
231
231
|
return sel(data || {}, children);
|
|
232
232
|
}
|
|
233
233
|
data || (data = {});
|
|
@@ -276,7 +276,7 @@ function vnode(sel, data, children, text, elm) {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
/* eslint-disable @typescript-eslint/no-namespace, import/export */
|
|
279
|
-
function Fragment(data, ...children) {
|
|
279
|
+
function Fragment$1(data, ...children) {
|
|
280
280
|
const flatChildren = flattenAndFilter(children, []);
|
|
281
281
|
if (flatChildren.length === 1 &&
|
|
282
282
|
!flatChildren[0].sel &&
|
|
@@ -311,6 +311,21 @@ function flattenAndFilter(children, flattened) {
|
|
|
311
311
|
return flattened;
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Local snabbdom re-export barrel.
|
|
316
|
+
*
|
|
317
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
318
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
319
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
320
|
+
*
|
|
321
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
322
|
+
* window guard.
|
|
323
|
+
*/
|
|
324
|
+
// Core
|
|
325
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
326
|
+
Fragment$1.__sygnalFragment = true;
|
|
327
|
+
const Fragment = Fragment$1;
|
|
328
|
+
|
|
314
329
|
function jsx(type, props, key) {
|
|
315
330
|
if (props == null)
|
|
316
331
|
return createElement(type, null);
|
|
@@ -225,7 +225,7 @@ const createElementWithModules = (modules) => {
|
|
|
225
225
|
console.error('JSX Error: Capitalized HTML element without corresponding factory function. Components with names where the first letter is capital MUST be defined or included at the parent component\'s file scope.');
|
|
226
226
|
}
|
|
227
227
|
if (fun(sel)) {
|
|
228
|
-
if (sel.name === 'Fragment') {
|
|
228
|
+
if (sel.__sygnalFragment || sel.name === 'Fragment') {
|
|
229
229
|
return sel(data || {}, children);
|
|
230
230
|
}
|
|
231
231
|
data || (data = {});
|
|
@@ -274,7 +274,7 @@ function vnode(sel, data, children, text, elm) {
|
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
/* eslint-disable @typescript-eslint/no-namespace, import/export */
|
|
277
|
-
function Fragment(data, ...children) {
|
|
277
|
+
function Fragment$1(data, ...children) {
|
|
278
278
|
const flatChildren = flattenAndFilter(children, []);
|
|
279
279
|
if (flatChildren.length === 1 &&
|
|
280
280
|
!flatChildren[0].sel &&
|
|
@@ -309,6 +309,21 @@ function flattenAndFilter(children, flattened) {
|
|
|
309
309
|
return flattened;
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Local snabbdom re-export barrel.
|
|
314
|
+
*
|
|
315
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
316
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
317
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
318
|
+
*
|
|
319
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
320
|
+
* window guard.
|
|
321
|
+
*/
|
|
322
|
+
// Core
|
|
323
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
324
|
+
Fragment$1.__sygnalFragment = true;
|
|
325
|
+
const Fragment = Fragment$1;
|
|
326
|
+
|
|
312
327
|
function jsx(type, props, key) {
|
|
313
328
|
if (props == null)
|
|
314
329
|
return createElement(type, null);
|
package/dist/jsx-runtime.cjs.js
CHANGED
|
@@ -227,7 +227,7 @@ const createElementWithModules = (modules) => {
|
|
|
227
227
|
console.error('JSX Error: Capitalized HTML element without corresponding factory function. Components with names where the first letter is capital MUST be defined or included at the parent component\'s file scope.');
|
|
228
228
|
}
|
|
229
229
|
if (fun(sel)) {
|
|
230
|
-
if (sel.name === 'Fragment') {
|
|
230
|
+
if (sel.__sygnalFragment || sel.name === 'Fragment') {
|
|
231
231
|
return sel(data || {}, children);
|
|
232
232
|
}
|
|
233
233
|
data || (data = {});
|
|
@@ -276,7 +276,7 @@ function vnode(sel, data, children, text, elm) {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
/* eslint-disable @typescript-eslint/no-namespace, import/export */
|
|
279
|
-
function Fragment(data, ...children) {
|
|
279
|
+
function Fragment$1(data, ...children) {
|
|
280
280
|
const flatChildren = flattenAndFilter(children, []);
|
|
281
281
|
if (flatChildren.length === 1 &&
|
|
282
282
|
!flatChildren[0].sel &&
|
|
@@ -311,6 +311,21 @@ function flattenAndFilter(children, flattened) {
|
|
|
311
311
|
return flattened;
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Local snabbdom re-export barrel.
|
|
316
|
+
*
|
|
317
|
+
* Imports from specific snabbdom subpaths instead of the main barrel to avoid
|
|
318
|
+
* triggering the broken `styleModule` top-level `window` reference in
|
|
319
|
+
* snabbdom 3.6.3 (which causes ReferenceError in Node.js environments).
|
|
320
|
+
*
|
|
321
|
+
* The styleModule is provided separately by ./styleModule.ts with a fixed
|
|
322
|
+
* window guard.
|
|
323
|
+
*/
|
|
324
|
+
// Core
|
|
325
|
+
// Tag Fragment so we can identify it even after minification mangles Function.name
|
|
326
|
+
Fragment$1.__sygnalFragment = true;
|
|
327
|
+
const Fragment = Fragment$1;
|
|
328
|
+
|
|
314
329
|
function jsx(type, props, key) {
|
|
315
330
|
if (props == null)
|
|
316
331
|
return createElement(type, null);
|