sygnal 5.3.6 → 5.4.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/README.md +53 -38
- package/dist/astro/client.cjs.js +18 -8106
- package/dist/astro/client.cjs.js.map +1 -0
- package/dist/astro/client.mjs +17 -8105
- package/dist/astro/client.mjs.map +1 -0
- package/dist/astro/index.cjs.js +768 -9
- package/dist/astro/index.cjs.js.map +1 -0
- package/dist/astro/index.mjs +768 -9
- package/dist/astro/index.mjs.map +1 -0
- package/dist/astro/server.cjs.js +4 -1
- package/dist/astro/server.cjs.js.map +1 -0
- package/dist/astro/server.mjs +4 -1
- package/dist/astro/server.mjs.map +1 -0
- package/dist/diagnostics.cjs.js +1297 -0
- package/dist/diagnostics.cjs.js.map +1 -0
- package/dist/diagnostics.esm.js +1267 -0
- package/dist/diagnostics.esm.js.map +1 -0
- package/dist/index.cjs.js +2981 -1386
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +848 -111
- package/dist/index.esm.js +2997 -1411
- package/dist/index.esm.js.map +1 -0
- package/dist/jsx-dev-runtime.cjs.js +15 -9
- package/dist/jsx-dev-runtime.cjs.js.map +1 -0
- package/dist/jsx-dev-runtime.esm.js +15 -9
- package/dist/jsx-dev-runtime.esm.js.map +1 -0
- package/dist/jsx-runtime.cjs.js +15 -9
- package/dist/jsx-runtime.cjs.js.map +1 -0
- package/dist/jsx-runtime.esm.js +15 -9
- package/dist/jsx-runtime.esm.js.map +1 -0
- package/dist/jsx.cjs.js +15 -9
- package/dist/jsx.cjs.js.map +1 -0
- package/dist/jsx.esm.js +15 -9
- package/dist/jsx.esm.js.map +1 -0
- package/dist/sygnal.min.js +2 -1
- package/dist/sygnal.min.js.map +1 -0
- package/dist/vike/+config.cjs.js +1 -0
- package/dist/vike/+config.cjs.js.map +1 -0
- package/dist/vike/+config.js +1 -0
- package/dist/vike/+config.js.map +1 -0
- package/dist/vike/ClientOnly.cjs.js +1 -0
- package/dist/vike/ClientOnly.cjs.js.map +1 -0
- package/dist/vike/ClientOnly.mjs +1 -0
- package/dist/vike/ClientOnly.mjs.map +1 -0
- package/dist/vike/onRenderClient.cjs.js +1 -0
- package/dist/vike/onRenderClient.cjs.js.map +1 -0
- package/dist/vike/onRenderClient.mjs +1 -0
- package/dist/vike/onRenderClient.mjs.map +1 -0
- package/dist/vike/onRenderHtml.cjs.js +1 -0
- package/dist/vike/onRenderHtml.cjs.js.map +1 -0
- package/dist/vike/onRenderHtml.mjs +1 -0
- package/dist/vike/onRenderHtml.mjs.map +1 -0
- package/dist/vite/plugin.cjs.js +680 -47
- package/dist/vite/plugin.cjs.js.map +1 -0
- package/dist/vite/plugin.mjs +680 -47
- package/dist/vite/plugin.mjs.map +1 -0
- package/llms.txt +250 -0
- package/package.json +15 -6
- package/src/astro/client.ts +13 -2
- package/src/astro/index.d.ts +24 -1
- package/src/astro/index.ts +40 -9
- package/src/astro/server.ts +3 -1
- package/src/collection.ts +5 -2
- package/src/component.ts +375 -330
- package/src/cycle/dom/MainDOMSource.ts +4 -0
- package/src/cycle/dom/classNameModule.ts +74 -0
- package/src/cycle/dom/controlledInputModule.ts +33 -0
- package/src/cycle/dom/enrichEventStream.ts +9 -3
- package/src/cycle/dom/makeDOMDriver.ts +1 -2
- package/src/cycle/dom/mockDOMSource.ts +62 -8
- package/src/cycle/dom/modules.ts +5 -1
- package/src/cycle/state/Collection.ts +13 -3
- package/src/cycle/state/StateSource.ts +1 -1
- package/src/cycle/state/pickCombine.ts +35 -1
- package/src/cycle/state/withState.ts +1 -1
- package/src/extra/devtools.ts +8 -0
- package/src/extra/diagnostics/checks/collections.ts +67 -0
- package/src/extra/diagnostics/checks/dom.ts +241 -0
- package/src/extra/diagnostics/checks/events.ts +68 -0
- package/src/extra/diagnostics/checks/index.ts +109 -0
- package/src/extra/diagnostics/checks/inspect.ts +319 -0
- package/src/extra/diagnostics/checks/props.ts +51 -0
- package/src/extra/diagnostics/checks/public.d.ts +211 -0
- package/src/extra/diagnostics/checks/rxjsHints.ts +88 -0
- package/src/extra/diagnostics/checks/shared.ts +119 -0
- package/src/extra/diagnostics/checks/state.ts +55 -0
- package/src/extra/diagnostics/checks/strict.ts +112 -0
- package/src/extra/diagnostics/checks/wiring.ts +65 -0
- package/src/extra/diagnostics/codes.ts +232 -0
- package/src/extra/diagnostics/index.ts +328 -0
- package/src/extra/diagnostics/legacy.ts +59 -0
- package/src/extra/driverFactories.ts +106 -58
- package/src/extra/eventDriver.ts +4 -0
- package/src/extra/flatten.ts +75 -0
- package/src/extra/reducers.ts +12 -5
- package/src/extra/run.ts +11 -0
- package/src/extra/testing.ts +890 -180
- package/src/extra/xstreamExtras.ts +269 -0
- package/src/index.d.ts +428 -17
- package/src/index.ts +7 -6
- package/src/pragma/index.ts +14 -9
- package/src/switchable.ts +10 -8
- package/src/vike/types.ts +21 -4
- package/src/vite/plugin.d.ts +95 -2
- package/src/vite/plugin.ts +730 -55
- package/dist/astro/astro/client.d.ts +0 -5
- package/dist/astro/astro/index.d.ts +0 -16
- package/dist/astro/astro/server.d.ts +0 -12
- package/dist/astro/client.d.ts +0 -5
- package/dist/astro/client.esm.js +0 -4665
- package/dist/astro/collection.d.ts +0 -12
- package/dist/astro/component.d.ts +0 -22
- package/dist/astro/cycle/dom/BodyDOMSource.d.ts +0 -10
- package/dist/astro/cycle/dom/DOMSource.d.ts +0 -11
- package/dist/astro/cycle/dom/DocumentDOMSource.d.ts +0 -12
- package/dist/astro/cycle/dom/ElementFinder.d.ts +0 -8
- package/dist/astro/cycle/dom/EventDelegator.d.ts +0 -34
- package/dist/astro/cycle/dom/IsolateModule.d.ts +0 -23
- package/dist/astro/cycle/dom/MainDOMSource.d.ts +0 -32
- package/dist/astro/cycle/dom/PriorityQueue.d.ts +0 -7
- package/dist/astro/cycle/dom/ScopeChecker.d.ts +0 -9
- package/dist/astro/cycle/dom/SymbolTree.d.ts +0 -9
- package/dist/astro/cycle/dom/VNodeWrapper.d.ts +0 -8
- package/dist/astro/cycle/dom/enrichEventStream.d.ts +0 -24
- package/dist/astro/cycle/dom/fromEvent.d.ts +0 -6
- package/dist/astro/cycle/dom/index.d.ts +0 -8
- package/dist/astro/cycle/dom/isolate.d.ts +0 -9
- package/dist/astro/cycle/dom/makeDOMDriver.d.ts +0 -11
- package/dist/astro/cycle/dom/mockDOMSource.d.ts +0 -17
- package/dist/astro/cycle/dom/modules.d.ts +0 -5
- package/dist/astro/cycle/dom/snabbdom.d.ts +0 -22
- package/dist/astro/cycle/dom/styleModule.d.ts +0 -13
- package/dist/astro/cycle/dom/thunk.d.ts +0 -11
- package/dist/astro/cycle/dom/utils.d.ts +0 -8
- package/dist/astro/cycle/isolate/index.d.ts +0 -42
- package/dist/astro/cycle/run/adapt.d.ts +0 -6
- package/dist/astro/cycle/run/index.d.ts +0 -36
- package/dist/astro/cycle/run/internals.d.ts +0 -8
- package/dist/astro/cycle/run/types.d.ts +0 -49
- package/dist/astro/cycle/state/Collection.d.ts +0 -29
- package/dist/astro/cycle/state/StateSource.d.ts +0 -20
- package/dist/astro/cycle/state/index.d.ts +0 -5
- package/dist/astro/cycle/state/pickCombine.d.ts +0 -3
- package/dist/astro/cycle/state/pickMerge.d.ts +0 -3
- package/dist/astro/cycle/state/types.d.ts +0 -18
- package/dist/astro/cycle/state/withState.d.ts +0 -17
- package/dist/astro/extra/classes.d.ts +0 -7
- package/dist/astro/extra/devtools.d.ts +0 -78
- package/dist/astro/extra/dragDriver.d.ts +0 -20
- package/dist/astro/extra/driverFactories.d.ts +0 -12
- package/dist/astro/extra/eventDriver.d.ts +0 -9
- package/dist/astro/extra/exactState.d.ts +0 -1
- package/dist/astro/extra/hmr.d.ts +0 -17
- package/dist/astro/extra/logDriver.d.ts +0 -2
- package/dist/astro/extra/processDrag.d.ts +0 -19
- package/dist/astro/extra/processForm.d.ts +0 -15
- package/dist/astro/extra/run.d.ts +0 -13
- package/dist/astro/extra/xstreamCompat.d.ts +0 -5
- package/dist/astro/index.d.ts +0 -19
- package/dist/astro/index.esm.js +0 -27
- package/dist/astro/jsx-dev-runtime.d.ts +0 -1
- package/dist/astro/jsx-runtime.d.ts +0 -4
- package/dist/astro/jsx.d.ts +0 -2
- package/dist/astro/pragma/fn.d.ts +0 -7
- package/dist/astro/pragma/index.d.ts +0 -7
- package/dist/astro/pragma/is.d.ts +0 -10
- package/dist/astro/server.d.ts +0 -12
- package/dist/astro/server.esm.js +0 -25
- package/dist/astro/switchable.d.ts +0 -7
- package/dist/collection.d.ts +0 -12
- package/dist/component.d.ts +0 -22
- package/dist/cycle/dom/BodyDOMSource.d.ts +0 -10
- package/dist/cycle/dom/DOMSource.d.ts +0 -11
- package/dist/cycle/dom/DocumentDOMSource.d.ts +0 -12
- package/dist/cycle/dom/ElementFinder.d.ts +0 -8
- package/dist/cycle/dom/EventDelegator.d.ts +0 -34
- package/dist/cycle/dom/IsolateModule.d.ts +0 -23
- package/dist/cycle/dom/MainDOMSource.d.ts +0 -32
- package/dist/cycle/dom/PriorityQueue.d.ts +0 -7
- package/dist/cycle/dom/ScopeChecker.d.ts +0 -9
- package/dist/cycle/dom/SymbolTree.d.ts +0 -9
- package/dist/cycle/dom/VNodeWrapper.d.ts +0 -8
- package/dist/cycle/dom/enrichEventStream.d.ts +0 -24
- package/dist/cycle/dom/fromEvent.d.ts +0 -6
- package/dist/cycle/dom/index.d.ts +0 -8
- package/dist/cycle/dom/isolate.d.ts +0 -9
- package/dist/cycle/dom/makeDOMDriver.d.ts +0 -11
- package/dist/cycle/dom/mockDOMSource.d.ts +0 -17
- package/dist/cycle/dom/modules.d.ts +0 -5
- package/dist/cycle/dom/snabbdom.d.ts +0 -22
- package/dist/cycle/dom/styleModule.d.ts +0 -13
- package/dist/cycle/dom/thunk.d.ts +0 -11
- package/dist/cycle/dom/utils.d.ts +0 -8
- package/dist/cycle/isolate/index.d.ts +0 -42
- package/dist/cycle/run/adapt.d.ts +0 -6
- package/dist/cycle/run/index.d.ts +0 -36
- package/dist/cycle/run/internals.d.ts +0 -8
- package/dist/cycle/run/types.d.ts +0 -49
- package/dist/cycle/state/Collection.d.ts +0 -29
- package/dist/cycle/state/StateSource.d.ts +0 -20
- package/dist/cycle/state/index.d.ts +0 -5
- package/dist/cycle/state/pickCombine.d.ts +0 -3
- package/dist/cycle/state/pickMerge.d.ts +0 -3
- package/dist/cycle/state/types.d.ts +0 -18
- package/dist/cycle/state/withState.d.ts +0 -17
- package/dist/extra/classes.d.ts +0 -7
- package/dist/extra/devtools.d.ts +0 -78
- package/dist/extra/dragDriver.d.ts +0 -20
- package/dist/extra/driverFactories.d.ts +0 -12
- package/dist/extra/eventDriver.d.ts +0 -9
- package/dist/extra/exactState.d.ts +0 -1
- package/dist/extra/hmr.d.ts +0 -17
- package/dist/extra/logDriver.d.ts +0 -2
- package/dist/extra/processDrag.d.ts +0 -19
- package/dist/extra/processForm.d.ts +0 -15
- package/dist/extra/run.d.ts +0 -13
- package/dist/extra/xstreamCompat.d.ts +0 -5
- package/dist/jsx-dev-runtime.d.ts +0 -1
- package/dist/jsx-dev-runtime.js +0 -224
- package/dist/jsx-runtime.d.ts +0 -4
- package/dist/jsx-runtime.js +0 -224
- package/dist/jsx.d.ts +0 -2
- package/dist/pragma/fn.d.ts +0 -7
- package/dist/pragma/index.d.ts +0 -7
- package/dist/pragma/is.d.ts +0 -10
- package/dist/switchable.d.ts +0 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,370 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import xsDefault, { Stream, MemoryStream } from 'xstream';
|
|
2
|
+
export { MemoryStream, Stream } from 'xstream';
|
|
3
|
+
import { VNode, VNodeData } from 'snabbdom/build/vnode.js';
|
|
4
|
+
export { VNode, VNodeData } from 'snabbdom/build/vnode.js';
|
|
5
|
+
export { default as debounce } from 'xstream/extra/debounce.js';
|
|
6
|
+
export { default as throttle } from 'xstream/extra/throttle.js';
|
|
7
|
+
export { default as delay } from 'xstream/extra/delay.js';
|
|
8
|
+
export { default as dropRepeats } from 'xstream/extra/dropRepeats.js';
|
|
9
|
+
export { default as sampleCombine } from 'xstream/extra/sampleCombine.js';
|
|
10
|
+
export { default as flattenConcurrently } from 'xstream/extra/flattenConcurrently.js';
|
|
11
|
+
export { default as flattenSequentially } from 'xstream/extra/flattenSequentially.js';
|
|
12
|
+
export { default as concat } from 'xstream/extra/concat.js';
|
|
13
|
+
export { h } from 'snabbdom/build/h.js';
|
|
14
|
+
import { Options } from 'snabbdom/build/init.js';
|
|
15
|
+
import { Module } from 'snabbdom/build/modules/module.js';
|
|
16
|
+
|
|
17
|
+
type Predicate = (ev: Event) => boolean;
|
|
18
|
+
type Comparator = Record<string, unknown>;
|
|
19
|
+
type PreventDefaultOpt = boolean | Predicate | Comparator;
|
|
20
|
+
|
|
21
|
+
interface EnrichedEventStream<T = Event> extends Stream<T> {
|
|
22
|
+
value(): EnrichedEventStream<string>;
|
|
23
|
+
value<R>(fn: (val: string) => R): EnrichedEventStream<R>;
|
|
24
|
+
checked(): EnrichedEventStream<boolean>;
|
|
25
|
+
checked<R>(fn: (val: boolean) => R): EnrichedEventStream<R>;
|
|
26
|
+
data(name: string): EnrichedEventStream<string | undefined>;
|
|
27
|
+
data<R>(name: string, fn: (val: string | undefined) => R): EnrichedEventStream<R>;
|
|
28
|
+
target(): EnrichedEventStream<EventTarget | null>;
|
|
29
|
+
target<R>(fn: (el: EventTarget | null) => R): EnrichedEventStream<R>;
|
|
30
|
+
key(): EnrichedEventStream<string>;
|
|
31
|
+
key<R>(fn: (key: string) => R): EnrichedEventStream<R>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare class DocumentDOMSource {
|
|
35
|
+
private _name;
|
|
36
|
+
private _selector;
|
|
37
|
+
constructor(_name: string, selector?: string);
|
|
38
|
+
select(selector: string): DocumentDOMSource;
|
|
39
|
+
elements(): MemoryStream<Array<Document | Element>>;
|
|
40
|
+
element(): MemoryStream<Document | Element | null>;
|
|
41
|
+
events<K extends keyof DocumentEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): EnrichedEventStream<DocumentEventMap[K]>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare class BodyDOMSource {
|
|
45
|
+
private _name;
|
|
46
|
+
constructor(_name: string);
|
|
47
|
+
select(selector: string): BodyDOMSource;
|
|
48
|
+
elements(): MemoryStream<Array<HTMLBodyElement>>;
|
|
49
|
+
element(): MemoryStream<HTMLBodyElement>;
|
|
50
|
+
events<K extends keyof HTMLBodyElementEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): Stream<HTMLBodyElementEventMap[K]>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface EventsFnOptions {
|
|
54
|
+
useCapture?: boolean;
|
|
55
|
+
passive?: boolean;
|
|
56
|
+
bubbles?: boolean;
|
|
57
|
+
preventDefault?: PreventDefaultOpt;
|
|
58
|
+
}
|
|
59
|
+
type DOMSource = MainDOMSource | DocumentDOMSource | BodyDOMSource;
|
|
60
|
+
|
|
61
|
+
interface Scope$1 {
|
|
62
|
+
type: 'sibling' | 'total' | 'selector';
|
|
63
|
+
scope: string;
|
|
64
|
+
}
|
|
65
|
+
type IsolateSink<T extends VNode> = (s: Stream<T>, scope: string) => Stream<T>;
|
|
66
|
+
|
|
67
|
+
interface CycleDOMEvent extends Event {
|
|
68
|
+
propagationHasBeenStopped: boolean;
|
|
69
|
+
ownerTarget: Element;
|
|
70
|
+
}
|
|
71
|
+
declare class EventDelegator {
|
|
72
|
+
private rootElement$;
|
|
73
|
+
isolateModule: IsolateModule;
|
|
74
|
+
private virtualListeners;
|
|
75
|
+
private origin;
|
|
76
|
+
private domListeners;
|
|
77
|
+
private nonBubblingListeners;
|
|
78
|
+
private domListenersToAdd;
|
|
79
|
+
private nonBubblingListenersToAdd;
|
|
80
|
+
private virtualNonBubblingListener;
|
|
81
|
+
constructor(rootElement$: Stream<Element>, isolateModule: IsolateModule);
|
|
82
|
+
addEventListener(eventType: string, namespace: Array<Scope$1>, options: EventsFnOptions, bubbles?: boolean): Stream<Event>;
|
|
83
|
+
removeElement(element: Element, namespace?: Array<Scope$1>): void;
|
|
84
|
+
private insertListener;
|
|
85
|
+
private getVirtualListeners;
|
|
86
|
+
private setupDOMListener;
|
|
87
|
+
private setupNonBubblingListener;
|
|
88
|
+
private resetEventListeners;
|
|
89
|
+
private putNonBubblingListener;
|
|
90
|
+
private onEvent;
|
|
91
|
+
private bubble;
|
|
92
|
+
private doBubbleStep;
|
|
93
|
+
private patchEvent;
|
|
94
|
+
private mutateEventCurrentTarget;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare class IsolateModule {
|
|
98
|
+
private namespaceTree;
|
|
99
|
+
private namespaceByElement;
|
|
100
|
+
private eventDelegator;
|
|
101
|
+
private vnodesBeingRemoved;
|
|
102
|
+
constructor();
|
|
103
|
+
setEventDelegator(del: EventDelegator): void;
|
|
104
|
+
private insertElement;
|
|
105
|
+
private removeElement;
|
|
106
|
+
getElement(namespace: Array<Scope$1>, max?: number): Element | undefined;
|
|
107
|
+
getRootElement(elm: Element): Element | undefined;
|
|
108
|
+
getNamespace(elm: Element): Array<Scope$1> | undefined;
|
|
109
|
+
createModule(): {
|
|
110
|
+
create(emptyVNode: VNode, vNode: VNode): void;
|
|
111
|
+
update(oldVNode: VNode, vNode: VNode): void;
|
|
112
|
+
destroy(vNode: VNode): void;
|
|
113
|
+
remove(vNode: VNode, cb: Function): void;
|
|
114
|
+
post(): void;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface SpecialSelector {
|
|
119
|
+
body: BodyDOMSource;
|
|
120
|
+
document: DocumentDOMSource;
|
|
121
|
+
}
|
|
122
|
+
declare class MainDOMSource {
|
|
123
|
+
private _rootElement$;
|
|
124
|
+
private _sanitation$;
|
|
125
|
+
private _namespace;
|
|
126
|
+
_isolateModule: IsolateModule;
|
|
127
|
+
private _eventDelegator;
|
|
128
|
+
private _name;
|
|
129
|
+
constructor(_rootElement$: Stream<Element>, _sanitation$: Stream<null>, _namespace: Array<Scope$1>, _isolateModule: IsolateModule, _eventDelegator: EventDelegator, _name: string);
|
|
130
|
+
private _elements;
|
|
131
|
+
elements(): MemoryStream<Array<Element>>;
|
|
132
|
+
element(): MemoryStream<Element>;
|
|
133
|
+
get namespace(): Array<Scope$1>;
|
|
134
|
+
select<T extends keyof SpecialSelector>(selector: T): SpecialSelector[T];
|
|
135
|
+
select(selector: string): MainDOMSource;
|
|
136
|
+
events<K extends keyof HTMLElementEventMap>(eventType: K, options?: EventsFnOptions, bubbles?: boolean): EnrichedEventStream<HTMLElementEventMap[K]>;
|
|
137
|
+
dispose(): void;
|
|
138
|
+
isolateSource: (source: MainDOMSource, scope: string) => MainDOMSource;
|
|
139
|
+
isolateSink: IsolateSink<VNode>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
type Reducer$1<T> = (state: T | undefined) => T | undefined;
|
|
143
|
+
type Getter<T, R> = (state: T | undefined) => R | undefined;
|
|
144
|
+
type Setter<T, R> = (state: T | undefined, childState: R | undefined) => T | undefined;
|
|
145
|
+
type Lens$1<T, R> = {
|
|
146
|
+
get: Getter<T, R>;
|
|
147
|
+
set: Setter<T, R>;
|
|
148
|
+
};
|
|
149
|
+
type Scope<T, R> = string | number | Lens$1<T, R>;
|
|
150
|
+
|
|
151
|
+
declare function isolateSource<T, R>(source: StateSource<T>, scope: Scope<T, R>): StateSource<R>;
|
|
152
|
+
declare function isolateSink<T, R>(innerReducer$: Stream<Reducer$1<R>>, scope: Scope<T, R>): Stream<Reducer$1<T>>;
|
|
153
|
+
/**
|
|
154
|
+
* Represents a piece of application state dynamically changing over time.
|
|
155
|
+
*/
|
|
156
|
+
declare class StateSource<S> {
|
|
157
|
+
stream: MemoryStream<S>;
|
|
158
|
+
private _stream;
|
|
159
|
+
private _name;
|
|
160
|
+
constructor(stream: Stream<S>, name: string);
|
|
161
|
+
/**
|
|
162
|
+
* Selects a part (or scope) of the state object and returns a new StateSource
|
|
163
|
+
* dynamically representing that selected part of the state.
|
|
164
|
+
*/
|
|
165
|
+
select<R>(scope: Scope<S, R>): StateSource<R>;
|
|
166
|
+
isolateSource: typeof isolateSource;
|
|
167
|
+
isolateSink: typeof isolateSink;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Types for the 'sygnal/diagnostics' entry (runtime consistency checks).
|
|
172
|
+
*
|
|
173
|
+
* import 'sygnal/diagnostics' // registers all checks (side effect)
|
|
174
|
+
*
|
|
175
|
+
* Checks only run while diagnostics are on: run(App, drivers, { diagnostics: 'warn' }),
|
|
176
|
+
* or globalThis.__SYGNAL_DEV__ (set by the Vite plugin in dev).
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
type DiagnosticSeverity$1 = 'error' | 'warn' | 'info'
|
|
180
|
+
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// inspect (PLAN-1 workstream 2B): a machine-readable app graph. The same shape
|
|
183
|
+
// is produced at runtime (inspect(), getDevTools().inspect(), renderComponent's
|
|
184
|
+
// t.inspect()) and statically (`sygnal-check --graph --json`); JSON Schema:
|
|
185
|
+
// sygnal-check/schema/inspect.schema.json. Fields one side cannot know are
|
|
186
|
+
// null (or omitted).
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
/** How an action is dispatched. */
|
|
190
|
+
type InspectActionTrigger = 'intent' | 'next' | 'builtin' | 'unknown'
|
|
191
|
+
|
|
192
|
+
interface InspectAction {
|
|
193
|
+
name: string
|
|
194
|
+
/**
|
|
195
|
+
* 'intent': returned by the component's intent. 'builtin': BOOTSTRAP,
|
|
196
|
+
* INITIALIZE, HYDRATE, DISPOSE or READY. 'next': dispatched with next()
|
|
197
|
+
* (statically: a next('NAME') literal; at runtime: a model-only action whose
|
|
198
|
+
* STATE reducer was seen running). 'unknown': none of these is known.
|
|
199
|
+
*/
|
|
200
|
+
trigger: InspectActionTrigger
|
|
201
|
+
/** sinks of the model entry (STATE, EVENTS, EFFECT, PARENT, custom drivers); [] without a model entry */
|
|
202
|
+
sinks: string[]
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface InspectChild {
|
|
206
|
+
name: string
|
|
207
|
+
via: 'tag' | 'collection' | 'switchable' | 'slot'
|
|
208
|
+
/** Collection: the `from` state field, when known */
|
|
209
|
+
from?: string | null
|
|
210
|
+
/** runtime: number of live instances behind this entry (e.g. Collection items) */
|
|
211
|
+
count?: number
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
interface InspectSelector {
|
|
215
|
+
/** CSS selector passed to DOM.select() (chained selects joined with a space) */
|
|
216
|
+
selector: string
|
|
217
|
+
/** event types listened to; null when unknown (runtime, real DOM) */
|
|
218
|
+
events: string[] | null
|
|
219
|
+
/**
|
|
220
|
+
* whether it matches an element the component itself renders; null when unknown.
|
|
221
|
+
* static: the class/id is in the view source. renderComponent: an element of the latest
|
|
222
|
+
* render matches (a conditionally rendered element that is hidden right now gives false).
|
|
223
|
+
* real DOM: true once a DOM check saw it match, false after SYG103/SYG104, else null.
|
|
224
|
+
*/
|
|
225
|
+
matched: boolean | null
|
|
226
|
+
/** the child component whose (isolated) elements it matches instead, if any */
|
|
227
|
+
isolationHit: string | null
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
interface InspectDiagnostic {
|
|
231
|
+
code: string
|
|
232
|
+
severity: DiagnosticSeverity$1
|
|
233
|
+
component?: string
|
|
234
|
+
message: string
|
|
235
|
+
fix?: string
|
|
236
|
+
docsUrl?: string
|
|
237
|
+
data?: any
|
|
238
|
+
/** static only */
|
|
239
|
+
file?: string
|
|
240
|
+
line?: number
|
|
241
|
+
column?: number
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface InspectComponent {
|
|
245
|
+
name: string
|
|
246
|
+
/** runtime: instance number (as a string); static: 'file:line' of the definition */
|
|
247
|
+
id: string
|
|
248
|
+
/** runtime: the parent instance's id; static: null (see the parents' `children`) */
|
|
249
|
+
parentId: string | null
|
|
250
|
+
/** static only: source file, relative to the working directory */
|
|
251
|
+
file?: string
|
|
252
|
+
/**
|
|
253
|
+
* runtime: how the instance was created; static: 'root' when no scanned
|
|
254
|
+
* component renders it, else how it is first rendered
|
|
255
|
+
*/
|
|
256
|
+
kind: 'root' | 'child' | 'collection-item' | 'switchable'
|
|
257
|
+
actions: InspectAction[]
|
|
258
|
+
/** state keys (runtime: current state; static: initialState) */
|
|
259
|
+
stateKeys: string[]
|
|
260
|
+
/** calculated field names */
|
|
261
|
+
calculated: string[]
|
|
262
|
+
/** context fields this component provides (Component.context) */
|
|
263
|
+
contextProvides: string[]
|
|
264
|
+
/** context fields its view reads (static only; null at runtime) */
|
|
265
|
+
contextConsumes?: string[] | null
|
|
266
|
+
/** EVENTS types this component emits */
|
|
267
|
+
eventsEmitted: string[]
|
|
268
|
+
/** EVENTS types this component selects ('*' = EVENTS.select() without a type) */
|
|
269
|
+
eventsSelected: string[]
|
|
270
|
+
children: InspectChild[]
|
|
271
|
+
selectors: InspectSelector[]
|
|
272
|
+
diagnostics: InspectDiagnostic[]
|
|
273
|
+
}
|
|
6
274
|
|
|
7
|
-
|
|
8
|
-
|
|
275
|
+
interface InspectGraph {
|
|
276
|
+
version: 1
|
|
277
|
+
/** which implementation produced the graph */
|
|
278
|
+
source?: 'runtime' | 'static'
|
|
279
|
+
components: InspectComponent[]
|
|
280
|
+
/** EVENTS bus: type -> names of the components that emit / select it */
|
|
281
|
+
events: Record<string, { emitters: string[]; selectors: string[] }>
|
|
282
|
+
/** diagnostics not tied to a listed component */
|
|
283
|
+
diagnostics: InspectDiagnostic[]
|
|
284
|
+
}
|
|
9
285
|
|
|
10
|
-
|
|
286
|
+
interface ThunkData extends VNodeData {
|
|
287
|
+
fn(): VNode;
|
|
288
|
+
args: Array<any>;
|
|
289
|
+
}
|
|
290
|
+
interface Thunk extends VNode {
|
|
291
|
+
data: ThunkData;
|
|
292
|
+
}
|
|
293
|
+
declare function thunk(sel: string, fn: Function, args: Array<any>): Thunk;
|
|
294
|
+
declare function thunk(sel: string, key: any, fn: Function, args: Array<any>): Thunk;
|
|
295
|
+
|
|
296
|
+
type FantasyObserver<T> = {
|
|
297
|
+
next(x: T): void;
|
|
298
|
+
error(err: any): void;
|
|
299
|
+
complete(c?: any): void;
|
|
300
|
+
};
|
|
301
|
+
type FantasySubscription = {
|
|
302
|
+
unsubscribe(): void;
|
|
303
|
+
};
|
|
304
|
+
type FantasyObservable<T> = {
|
|
305
|
+
subscribe(observer: FantasyObserver<T>): FantasySubscription;
|
|
306
|
+
};
|
|
307
|
+
type Driver<Si, So> = Si extends void ? (() => So) : ((stream: Si) => So);
|
|
308
|
+
|
|
309
|
+
interface DOMDriverOptions {
|
|
310
|
+
modules?: Array<Partial<Module>>;
|
|
311
|
+
reportSnabbdomError?(err: unknown): void;
|
|
312
|
+
snabbdomOptions?: Options;
|
|
313
|
+
}
|
|
314
|
+
declare function makeDOMDriver(container: string | Element | DocumentFragment, options?: DOMDriverOptions): Driver<Stream<VNode>, MainDOMSource>;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Optional simulated-event hub (used by renderComponent's simulateEvent): a
|
|
318
|
+
* stream of `{type, event, match(path)}`; each source's events(type) also emits
|
|
319
|
+
* the hub events whose `match` accepts its selector path (isolation scopes
|
|
320
|
+
* included as '.___scope' segments).
|
|
321
|
+
*/
|
|
322
|
+
type MockEventHub = Stream<{
|
|
323
|
+
type: string;
|
|
324
|
+
event: any;
|
|
325
|
+
match: (path: string[]) => boolean;
|
|
326
|
+
}>;
|
|
327
|
+
/**
|
|
328
|
+
* Optional listener callback (renderComponent): called with `live` undefined when events() is
|
|
329
|
+
* called (SYG103/104 checks), then with true / false when that hub listener is subscribed /
|
|
330
|
+
* unsubscribed (simulateEvent waits for a just-mounted child's listeners, G-039).
|
|
331
|
+
*/
|
|
332
|
+
type MockOnEvents = (path: string[], eventType: string, live?: boolean) => void;
|
|
333
|
+
type MockConfig = {
|
|
334
|
+
[name: string]: FantasyObservable<any> | MockConfig;
|
|
335
|
+
};
|
|
336
|
+
declare class MockedDOMSource {
|
|
337
|
+
private _mockConfig;
|
|
338
|
+
private _hub?;
|
|
339
|
+
_path: string[];
|
|
340
|
+
private _onEvents?;
|
|
341
|
+
private _elements;
|
|
342
|
+
constructor(_mockConfig: MockConfig, _hub?: MockEventHub | undefined, _path?: string[], _onEvents?: MockOnEvents | undefined);
|
|
343
|
+
elements(): any;
|
|
344
|
+
element(): any;
|
|
345
|
+
events(eventType: string, options?: EventsFnOptions, bubbles?: boolean): any;
|
|
346
|
+
select(selector: string): MockedDOMSource;
|
|
347
|
+
isolateSource(source: MockedDOMSource, scope: string): MockedDOMSource;
|
|
348
|
+
isolateSink(sink: any, scope: string): any;
|
|
349
|
+
}
|
|
350
|
+
declare function mockDOMSource(mockConfig: MockConfig, hub?: MockEventHub, onEvents?: MockOnEvents): MockedDOMSource;
|
|
351
|
+
|
|
352
|
+
declare const ABORT: unique symbol
|
|
353
|
+
type ABORT = typeof ABORT
|
|
354
|
+
|
|
355
|
+
type DriverSpec<SOURCE = any, SINK = any> = {
|
|
11
356
|
source: SOURCE;
|
|
12
357
|
sink: SINK;
|
|
13
358
|
}
|
|
14
359
|
|
|
15
|
-
|
|
360
|
+
type DriverSpecs = Record<string, DriverSpec<any, any>>
|
|
16
361
|
|
|
17
|
-
|
|
362
|
+
type CycleDriver<SINK = any, SOURCE = any> =
|
|
18
363
|
SINK extends void
|
|
19
364
|
? (() => SOURCE)
|
|
20
365
|
: ((sink$: Stream<SINK>) => SOURCE)
|
|
21
366
|
|
|
22
|
-
|
|
367
|
+
type DriverFactories<DRIVERS extends DriverSpecs = DriverSpecs> = {
|
|
23
368
|
[DRIVER_KEY in keyof DRIVERS]: CycleDriver<DRIVERS[DRIVER_KEY]['sink'], DRIVERS[DRIVER_KEY]['source']>
|
|
24
369
|
}
|
|
25
370
|
|
|
@@ -51,23 +396,89 @@ type Reducer<STATE, PROPS, ACTIONS = any, DATA = any, RETURN = any, CONTEXT = {}
|
|
|
51
396
|
props: ReducerExtras<PROPS, CONTEXT>
|
|
52
397
|
) => RETURN | ABORT | undefined
|
|
53
398
|
|
|
54
|
-
|
|
399
|
+
type ExactShape<EXPECTED, ACTUAL extends EXPECTED> = ACTUAL &
|
|
55
400
|
Record<Exclude<keyof ACTUAL, keyof EXPECTED>, never>
|
|
56
401
|
|
|
57
402
|
type StateOnlyReducer<STATE, RETURN = any> = (
|
|
58
403
|
state: STATE
|
|
59
404
|
) => RETURN | ABORT
|
|
60
405
|
|
|
61
|
-
|
|
406
|
+
type Event$1<DATA = any> = { type: string; data: DATA }
|
|
407
|
+
|
|
408
|
+
// ── EVENTS registry ────────────────────────────────────────────────
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Registry of global EVENTS bus event names and their payload types.
|
|
412
|
+
*
|
|
413
|
+
* Empty by default, which keeps the EVENTS bus untyped (`any`). Augment it to
|
|
414
|
+
* type-check `EVENTS.select()`, `event()`, `emit()` and raw EVENTS sink returns:
|
|
415
|
+
*
|
|
416
|
+
* declare module 'sygnal' {
|
|
417
|
+
* interface SygnalEvents {
|
|
418
|
+
* DELETE_LANE: { laneId: string }
|
|
419
|
+
* RESET: void // no payload: event('RESET')
|
|
420
|
+
* }
|
|
421
|
+
* }
|
|
422
|
+
*
|
|
423
|
+
* Once the registry has at least one entry, unregistered event names are type errors.
|
|
424
|
+
* The augmenting file must be a module (have at least one import or export).
|
|
425
|
+
*/
|
|
426
|
+
interface SygnalEvents {}
|
|
427
|
+
|
|
428
|
+
/** Valid event names: `string` while the registry is empty, otherwise the registered names. */
|
|
429
|
+
type EventName = keyof SygnalEvents extends never ? string : keyof SygnalEvents & string
|
|
430
|
+
|
|
431
|
+
/** Payload type of a registered event (`any` while the registry is empty). */
|
|
432
|
+
type EventPayload<TYPE extends string = string> = keyof SygnalEvents extends never
|
|
433
|
+
? any
|
|
434
|
+
: TYPE extends keyof SygnalEvents ? SygnalEvents[TYPE] : never
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* An event object as put on the EVENTS bus. While the registry is empty this is `Event<any>`;
|
|
438
|
+
* otherwise it is the union of `{ type, data }` for every registered event.
|
|
439
|
+
*/
|
|
440
|
+
type RegisteredEvent = keyof SygnalEvents extends never
|
|
441
|
+
? Event$1<any>
|
|
442
|
+
: { [TYPE in keyof SygnalEvents & string]: { type: TYPE; data: SygnalEvents[TYPE] } }[keyof SygnalEvents & string]
|
|
62
443
|
|
|
63
|
-
|
|
444
|
+
/** The `{ type, data }` object produced by `event(type, ...)` / `emit(type, ...)`. */
|
|
445
|
+
type EmittedEvent<TYPE extends string = string> = keyof SygnalEvents extends never
|
|
446
|
+
? { type: TYPE; data: any }
|
|
447
|
+
: { type: TYPE; data: EventPayload<TYPE> }
|
|
448
|
+
|
|
449
|
+
/** The `next()` function as seen by an event payload function. */
|
|
450
|
+
type EventNextFunction = (action: string, data?: any, delay?: number) => void
|
|
451
|
+
|
|
452
|
+
/** Payload function for `event()` / `emit()`: receives the reducer arguments, returns the event data. */
|
|
453
|
+
type EventPayloadFunction<TYPE extends string = string, STATE = any, DATA = any> =
|
|
454
|
+
(state: STATE, data: DATA, next: EventNextFunction, props: any) => EventPayload<TYPE>
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Remaining arguments of `event()` / `emit()` when the payload is a static value.
|
|
458
|
+
* The payload may be omitted when the registry is empty or the event's payload
|
|
459
|
+
* type accepts `undefined` (e.g. `void`).
|
|
460
|
+
*/
|
|
461
|
+
type StaticEventArgs<TYPE extends string> = keyof SygnalEvents extends never
|
|
462
|
+
? [payload?: any]
|
|
463
|
+
: undefined extends EventPayload<TYPE>
|
|
464
|
+
? [payload?: EventPayload<TYPE>]
|
|
465
|
+
: [payload: EventPayload<TYPE>]
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* The sink function returned by `event()`. Use it as the value of an `EVENTS` key in a
|
|
469
|
+
* model entry: `ACTION: { STATE: ..., EVENTS: event('TYPE', fn) }`.
|
|
470
|
+
*/
|
|
471
|
+
type EventSink<TYPE extends string = string, STATE = any, DATA = any> =
|
|
472
|
+
(state: STATE, data: DATA, next: any, props: any) => EmittedEvent<TYPE>
|
|
473
|
+
|
|
474
|
+
type NonStateSinkReturns = {
|
|
64
475
|
EVENTS?: unknown;
|
|
65
476
|
LOG?: unknown;
|
|
66
477
|
PARENT?: unknown;
|
|
67
478
|
}
|
|
68
479
|
|
|
69
480
|
type ResolvedNonStateSinkReturns<SINK_RETURNS extends NonStateSinkReturns = {}> = {
|
|
70
|
-
EVENTS: SINK_RETURNS extends { EVENTS: infer EVENTS_RETURN } ? EVENTS_RETURN :
|
|
481
|
+
EVENTS: SINK_RETURNS extends { EVENTS: infer EVENTS_RETURN } ? EVENTS_RETURN : RegisteredEvent;
|
|
71
482
|
LOG: SINK_RETURNS extends { LOG: infer LOG_RETURN } ? LOG_RETURN : any;
|
|
72
483
|
PARENT: SINK_RETURNS extends { PARENT: infer PARENT_RETURN } ? PARENT_RETURN : any;
|
|
73
484
|
}
|
|
@@ -149,20 +560,58 @@ type ComponentModel<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, SINK_RETURNS ext
|
|
|
149
560
|
>
|
|
150
561
|
}
|
|
151
562
|
|
|
563
|
+
type TrimSpaces<S extends string> =
|
|
564
|
+
S extends ` ${infer REST}` ? TrimSpaces<REST>
|
|
565
|
+
: S extends `${infer REST} ` ? TrimSpaces<REST>
|
|
566
|
+
: S
|
|
567
|
+
|
|
568
|
+
/** Value type produced by a PARENT sink value (a reducer's return, minus ABORT/undefined). */
|
|
569
|
+
type ParentSinkValueReturn<VALUE> =
|
|
570
|
+
VALUE extends (...args: any[]) => infer RETURN ? Exclude<RETURN, ABORT | undefined | void> : never
|
|
571
|
+
|
|
572
|
+
type ParentPayloadFromEntry<ENTRY> =
|
|
573
|
+
ENTRY extends (...args: any[]) => any ? never
|
|
574
|
+
: ENTRY extends object
|
|
575
|
+
? 'PARENT' extends keyof ENTRY ? ParentSinkValueReturn<NonNullable<ENTRY['PARENT']>> : never
|
|
576
|
+
: never
|
|
577
|
+
|
|
578
|
+
type ParentPayloadsOfModel<MODEL> = {
|
|
579
|
+
[ACTION_KEY in keyof MODEL]-?: ACTION_KEY extends `${string}|${infer SINK}`
|
|
580
|
+
? TrimSpaces<SINK> extends 'PARENT' ? ParentSinkValueReturn<NonNullable<MODEL[ACTION_KEY]>> : never
|
|
581
|
+
: ParentPayloadFromEntry<NonNullable<MODEL[ACTION_KEY]>>
|
|
582
|
+
}[keyof MODEL]
|
|
583
|
+
|
|
584
|
+
type AnyIfNever<T> = [T] extends [never] ? any : T
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* The value type a component sends to its parent through the `PARENT` sink, inferred from the
|
|
588
|
+
* component's `model` (object-form `{ PARENT: fn }` entries and `'ACTION | PARENT'` shorthand).
|
|
589
|
+
* Falls back to `any` when it can't be inferred (no model, a `Component<...>` annotation without
|
|
590
|
+
* a `PARENT` entry in its `SINK_RETURNS`, or `PARENT: true` pass-through entries only).
|
|
591
|
+
*/
|
|
592
|
+
type ParentPayloadOf<COMPONENT> =
|
|
593
|
+
COMPONENT extends { model?: infer MODEL }
|
|
594
|
+
? 0 extends (1 & MODEL) ? any : AnyIfNever<ParentPayloadsOfModel<NonNullable<MODEL>>>
|
|
595
|
+
: any
|
|
596
|
+
|
|
152
597
|
type ChildSource = {
|
|
598
|
+
/** Typed: the stream type is inferred from the child's PARENT sink (falls back to `any`). */
|
|
599
|
+
select<COMPONENT extends (...args: any[]) => any>(component: COMPONENT): Stream<ParentPayloadOf<COMPONENT>>;
|
|
153
600
|
select<T = any>(component: (...args: any[]) => any): Stream<T>;
|
|
154
601
|
select<T = any>(name: string): Stream<T>;
|
|
155
602
|
}
|
|
156
603
|
|
|
157
|
-
|
|
604
|
+
type SygnalDOMSource = MainDOMSource & {
|
|
158
605
|
[eventName: string]: (selector: string) => EnrichedEventStream<globalThis.Event>
|
|
159
606
|
}
|
|
160
607
|
|
|
161
|
-
|
|
162
|
-
select<T = any>(type: string): Stream<T>;
|
|
163
|
-
}
|
|
608
|
+
type EventsSelect = keyof SygnalEvents extends never
|
|
609
|
+
? { select<T = any>(type: string): Stream<T>; }
|
|
610
|
+
: { select<TYPE extends keyof SygnalEvents & string>(type: TYPE): Stream<SygnalEvents[TYPE]>; }
|
|
164
611
|
|
|
165
|
-
|
|
612
|
+
type EventsSource<EVENTS = any> = Stream<Event$1<EVENTS>> & EventsSelect
|
|
613
|
+
|
|
614
|
+
type DefaultDrivers<STATE, EVENTS = any> = {
|
|
166
615
|
STATE: {
|
|
167
616
|
source: StateSource<STATE>;
|
|
168
617
|
sink: STATE;
|
|
@@ -204,7 +653,7 @@ type IntentActions<ACTIONS> = keyof ACTIONS extends never
|
|
|
204
653
|
* Supports both `type` aliases and `interface` declarations (interfaces lack implicit index
|
|
205
654
|
* signatures, so a structural fallback check is needed).
|
|
206
655
|
*/
|
|
207
|
-
|
|
656
|
+
type FixDrivers<DRIVERS> =
|
|
208
657
|
0 extends (1 & DRIVERS)
|
|
209
658
|
? {}
|
|
210
659
|
: DRIVERS extends DriverSpecs
|
|
@@ -217,6 +666,42 @@ export type FixDrivers<DRIVERS> =
|
|
|
217
666
|
|
|
218
667
|
type CombinedSources<STATE, DRIVERS> = Sources<DefaultDrivers<STATE> & DRIVERS> & { dispose$: Stream<boolean> }
|
|
219
668
|
|
|
669
|
+
/**
|
|
670
|
+
* The sources object an intent function receives (DOM, STATE, EVENTS, CHILD, dispose$, plus
|
|
671
|
+
* any custom drivers). Use it to annotate an intent declared before its component:
|
|
672
|
+
*
|
|
673
|
+
* const intent = ({ DOM }: IntentSources<State>) => ({ INC: DOM.click('.inc') })
|
|
674
|
+
*/
|
|
675
|
+
type IntentSources<STATE = any, DRIVERS = {}> = CombinedSources<STATE, FixDrivers<DRIVERS>>
|
|
676
|
+
|
|
677
|
+
type StreamPayload<STREAM> = STREAM extends Stream<infer T> ? T : any
|
|
678
|
+
|
|
679
|
+
type IntentReturnToActions<RETURN> = {
|
|
680
|
+
[ACTION_KEY in keyof RETURN & string]-?: StreamPayload<Exclude<RETURN[ACTION_KEY], undefined>>
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Derives the ACTIONS map (action name → payload type) from an intent function's type
|
|
685
|
+
* (or from its return object type): each key's `Stream<T>` becomes `T`.
|
|
686
|
+
*
|
|
687
|
+
* const intent = ({ DOM }: IntentSources<State>) => ({
|
|
688
|
+
* INC: DOM.click('.inc').mapTo(1), // Stream<number>
|
|
689
|
+
* NAME: DOM.input('.name').value(), // Stream<string>
|
|
690
|
+
* })
|
|
691
|
+
* const Counter: Component<State, {}, {}, ActionsOf<typeof intent>> = ...
|
|
692
|
+
* Counter.intent = intent
|
|
693
|
+
* Counter.model = { INC: (state, n) => ..., NAME: (state, name) => ... } // n: number, name: string
|
|
694
|
+
*
|
|
695
|
+
* With it, model keys not returned by the intent are type errors (the built-ins BOOTSTRAP,
|
|
696
|
+
* INITIALIZE, HYDRATE and DISPOSE stay allowed). Actions reached only through `next()` are
|
|
697
|
+
* added explicitly:
|
|
698
|
+
*
|
|
699
|
+
* type Actions = ActionsOf<typeof intent> & { SAVED: { id: string } }
|
|
700
|
+
*/
|
|
701
|
+
type ActionsOf<INTENT> = INTENT extends (...args: any[]) => infer RETURN
|
|
702
|
+
? IntentReturnToActions<RETURN>
|
|
703
|
+
: IntentReturnToActions<INTENT>
|
|
704
|
+
|
|
220
705
|
interface ComponentIntent<STATE, DRIVERS, ACTIONS> {
|
|
221
706
|
(args: CombinedSources<STATE, DRIVERS>): Partial<IntentActions<ACTIONS>>
|
|
222
707
|
}
|
|
@@ -233,25 +718,25 @@ type Context<STATE, CONTEXT> = keyof CONTEXT extends never
|
|
|
233
718
|
? { [field: string]: boolean | StateOnlyReducer<STATE, any> }
|
|
234
719
|
: { [CONTEXT_KEY in keyof CONTEXT]: boolean | StateOnlyReducer<STATE, CONTEXT[CONTEXT_KEY]> }
|
|
235
720
|
|
|
236
|
-
|
|
721
|
+
type Lense<PARENT_STATE = any, CHILD_STATE = any> = {
|
|
237
722
|
get: (state: PARENT_STATE) => CHILD_STATE;
|
|
238
723
|
set: (state: PARENT_STATE, childState: CHILD_STATE) => PARENT_STATE;
|
|
239
724
|
}
|
|
240
725
|
|
|
241
|
-
|
|
726
|
+
type Lens<PARENT_STATE = any, CHILD_STATE = any> = Lense<PARENT_STATE, CHILD_STATE>
|
|
242
727
|
|
|
243
|
-
|
|
728
|
+
type Filter<ITEM = any> = (item: ITEM) => boolean
|
|
244
729
|
|
|
245
|
-
|
|
730
|
+
type SortFunction<ITEM = any> = (a: ITEM, b: ITEM) => number
|
|
246
731
|
|
|
247
|
-
|
|
732
|
+
type SortObject<ITEM = any> = {
|
|
248
733
|
[field: string]: 'asc' | 'desc' | SortFunction<ITEM>
|
|
249
734
|
}
|
|
250
735
|
|
|
251
736
|
/**
|
|
252
737
|
* Sygnal Component
|
|
253
738
|
*/
|
|
254
|
-
|
|
739
|
+
type Component<
|
|
255
740
|
STATE = any,
|
|
256
741
|
PROPS = { [prop: string]: any },
|
|
257
742
|
DRIVERS = {},
|
|
@@ -267,6 +752,12 @@ export type Component<
|
|
|
267
752
|
model?: ComponentModel<STATE, PROPS, FixDrivers<DRIVERS>, ACTIONS, CALCULATED, SINK_RETURNS, CONTEXT>;
|
|
268
753
|
intent?: ComponentIntent<STATE & CALCULATED, FixDrivers<DRIVERS>, ACTIONS>;
|
|
269
754
|
initialState?: STATE;
|
|
755
|
+
/**
|
|
756
|
+
* Give a sub-component its own state instead of the slice its parent passes in.
|
|
757
|
+
* Required to use `initialState` on a sub-component (otherwise SYG405). Without a
|
|
758
|
+
* `state` prop the state is local to the instance and never written to the parent.
|
|
759
|
+
*/
|
|
760
|
+
isolatedState?: boolean;
|
|
270
761
|
calculated?: Calculated<STATE, CALCULATED>;
|
|
271
762
|
storeCalculatedInState?: boolean;
|
|
272
763
|
context?: Context<STATE & CALCULATED, CONTEXT>;
|
|
@@ -279,7 +770,7 @@ export type Component<
|
|
|
279
770
|
/**
|
|
280
771
|
* Sygnal Root Component
|
|
281
772
|
*/
|
|
282
|
-
|
|
773
|
+
type RootComponent<
|
|
283
774
|
STATE = any,
|
|
284
775
|
DRIVERS = {},
|
|
285
776
|
ACTIONS = {},
|
|
@@ -294,68 +785,175 @@ export type RootComponent<
|
|
|
294
785
|
*/
|
|
295
786
|
type AnyComponent = ((...args: any[]) => any) & Record<string, any>
|
|
296
787
|
|
|
297
|
-
|
|
788
|
+
/** Keys of STATE whose value is an array (optional/nullable arrays included). */
|
|
789
|
+
type ArrayKeysOf<STATE> = {
|
|
790
|
+
[KEY in keyof STATE]-?: NonNullable<STATE[KEY]> extends ReadonlyArray<any> ? KEY : never
|
|
791
|
+
}[keyof STATE] & string
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* Valid `from` values for a Collection: any string or Lense while the parent STATE is unknown
|
|
795
|
+
* (`any`); otherwise an array-valued key of STATE or a Lense over STATE.
|
|
796
|
+
*/
|
|
797
|
+
type CollectionFrom<STATE = any> = 0 extends (1 & STATE)
|
|
798
|
+
? string | Lense
|
|
799
|
+
: ArrayKeysOf<STATE> | Lense<STATE, any>
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Collection props. Pass the parent component's state type as STATE to type-check `from`:
|
|
803
|
+
*
|
|
804
|
+
* const TaskCollection = Collection<{}, LaneState> // instantiation expression
|
|
805
|
+
* <TaskCollection of={TaskCard} from="tasks" /> // 'tasks' must be an array key of LaneState
|
|
806
|
+
*/
|
|
807
|
+
type CollectionProps<PROPS = any, STATE = any> = {
|
|
298
808
|
of: AnyComponent;
|
|
299
|
-
from:
|
|
809
|
+
from: CollectionFrom<STATE>;
|
|
300
810
|
filter?: Filter;
|
|
301
811
|
sort?: string | SortFunction | SortObject;
|
|
302
|
-
|
|
812
|
+
/**
|
|
813
|
+
* Item field used as the key that tracks each item (its component instance, isolation
|
|
814
|
+
* scope and DOM) across updates. Items are keyed by `id` by default; keys should be
|
|
815
|
+
* unique and stable (an item without the field is keyed by its index).
|
|
816
|
+
*/
|
|
817
|
+
idfield?: string;
|
|
818
|
+
} & Omit<PROPS, 'of' | 'from' | 'filter' | 'sort' | 'idfield'>
|
|
303
819
|
|
|
304
|
-
|
|
820
|
+
type SwitchableProps<PROPS = any> = {
|
|
305
821
|
of: Record<string, AnyComponent>;
|
|
306
822
|
current: string;
|
|
307
823
|
state?: string | Lense;
|
|
308
824
|
} & Omit<PROPS, 'of' | 'state' | 'current'>
|
|
309
825
|
|
|
310
|
-
|
|
826
|
+
type PortalProps = {
|
|
311
827
|
target: string;
|
|
312
828
|
children?: any;
|
|
313
829
|
}
|
|
314
830
|
|
|
315
|
-
|
|
831
|
+
type TransitionProps = {
|
|
316
832
|
name?: string;
|
|
317
833
|
duration?: number;
|
|
318
834
|
appear?: boolean;
|
|
319
835
|
children?: any;
|
|
320
836
|
}
|
|
321
837
|
|
|
322
|
-
|
|
838
|
+
type SuspenseProps = {
|
|
839
|
+
/**
|
|
840
|
+
* Shown (wrapped in `<div data-sygnal-suspense="pending">`) while any child is not ready:
|
|
841
|
+
* a `lazy()` component still loading, or a component with an explicit READY model entry
|
|
842
|
+
* that hasn't emitted true. A string renders as text. Without it the children render as-is.
|
|
843
|
+
*/
|
|
844
|
+
fallback?: JSX.Element | string;
|
|
845
|
+
children?: any;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
type SlotProps = {
|
|
323
849
|
name?: string;
|
|
324
850
|
children?: any;
|
|
325
851
|
}
|
|
326
852
|
|
|
327
|
-
|
|
853
|
+
type ClassesType = (string | string[] | { [className: string]: boolean | undefined })[]
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Diagnostics mode.
|
|
857
|
+
* - 'off' — no checks, no collection (default in production)
|
|
858
|
+
* - 'collect' — collect diagnostics silently (read with getDiagnostics())
|
|
859
|
+
* - 'warn' — collect and print warn/error diagnostics to the console (default in Vite dev)
|
|
860
|
+
* - 'error' — collect and throw on warn/error diagnostics
|
|
861
|
+
*/
|
|
862
|
+
type DiagnosticsMode = 'off' | 'collect' | 'warn' | 'error'
|
|
863
|
+
|
|
864
|
+
/** Stable diagnostic code, e.g. 'SYG101'. See https://sygnal.js.org/reference/errors */
|
|
865
|
+
type DiagnosticCode = `SYG${number}`
|
|
866
|
+
|
|
867
|
+
type DiagnosticSeverity = 'error' | 'warn' | 'info'
|
|
868
|
+
|
|
869
|
+
type Diagnostic = {
|
|
870
|
+
code: DiagnosticCode;
|
|
871
|
+
severity: DiagnosticSeverity;
|
|
872
|
+
/** Name of the component the diagnostic is about */
|
|
873
|
+
component?: string;
|
|
874
|
+
/** What is wrong */
|
|
875
|
+
message: string;
|
|
876
|
+
/** How to fix it */
|
|
877
|
+
fix?: string;
|
|
878
|
+
/** Structured payload (check-specific) */
|
|
879
|
+
data?: any;
|
|
880
|
+
/** Link to the docs entry for this code */
|
|
881
|
+
docsUrl: string;
|
|
882
|
+
/** Fully formatted message: `[Sygnal SYG123] Component: message. fix docsUrl` */
|
|
883
|
+
text: string;
|
|
884
|
+
timestamp: number;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
type DiagnosticsOptions = {
|
|
888
|
+
mode?: DiagnosticsMode;
|
|
889
|
+
/** Codes to ignore entirely */
|
|
890
|
+
ignore?: DiagnosticCode[];
|
|
891
|
+
}
|
|
328
892
|
|
|
329
|
-
|
|
893
|
+
type RunOptions = {
|
|
330
894
|
mountPoint?: string;
|
|
331
895
|
fragments?: boolean;
|
|
332
896
|
useDefaultDrivers?: boolean;
|
|
897
|
+
/**
|
|
898
|
+
* Runtime diagnostics. Takes precedence over `globalThis.__SYGNAL_DEV__`
|
|
899
|
+
* (set by the Sygnal Vite plugin in dev), which enables 'warn'. Default: 'off'.
|
|
900
|
+
*/
|
|
901
|
+
diagnostics?: DiagnosticsMode | DiagnosticsOptions;
|
|
333
902
|
}
|
|
334
903
|
|
|
335
|
-
|
|
904
|
+
/** All diagnostics collected so far (most recent last). */
|
|
905
|
+
declare function getDiagnostics(): Diagnostic[]
|
|
906
|
+
|
|
907
|
+
/** Clear the collected diagnostics. */
|
|
908
|
+
declare function clearDiagnostics(): void
|
|
909
|
+
|
|
910
|
+
/** Subscribe to diagnostics as they are reported. Returns an unsubscribe function. */
|
|
911
|
+
declare function onDiagnostic(callback: (diagnostic: Diagnostic) => void): () => void
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* The Sygnal DevTools bridge (also `window.__SYGNAL_DEVTOOLS__` once run() has
|
|
916
|
+
* initialized it in a browser). Only the stable, documented members are typed.
|
|
917
|
+
*/
|
|
918
|
+
interface SygnalDevTools {
|
|
919
|
+
/** true while the browser extension is connected */
|
|
920
|
+
readonly connected: boolean
|
|
921
|
+
/** Diagnostics collected so far (same as getDiagnostics()) */
|
|
922
|
+
getDiagnostics(): Diagnostic[]
|
|
923
|
+
/**
|
|
924
|
+
* The machine-readable app graph of the live components. Present only when the
|
|
925
|
+
* 'sygnal/diagnostics' dev entry is loaded (it attaches this method); needs diagnostics on.
|
|
926
|
+
*/
|
|
927
|
+
inspect?(): InspectGraph
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/** The DevTools bridge singleton. */
|
|
931
|
+
declare function getDevTools(): SygnalDevTools | undefined
|
|
932
|
+
|
|
933
|
+
type SygnalSinks<STATE = any, DRIVERS = {}> = {
|
|
336
934
|
[SINK_NAME in keyof (DefaultDrivers<STATE> & FixDrivers<DRIVERS>) | string]?: Stream<any>
|
|
337
935
|
}
|
|
338
936
|
|
|
339
|
-
|
|
937
|
+
type AnyComponentModule<COMPONENT = any> =
|
|
340
938
|
| COMPONENT
|
|
341
939
|
| { default: COMPONENT }
|
|
342
940
|
| Array<COMPONENT | { default: COMPONENT } | null | undefined>
|
|
343
941
|
| null
|
|
344
942
|
| undefined
|
|
345
943
|
|
|
346
|
-
|
|
944
|
+
type SygnalApp<STATE = any, DRIVERS = {}> = {
|
|
347
945
|
sources: CombinedSources<STATE, FixDrivers<DRIVERS>>;
|
|
348
946
|
sinks: SygnalSinks<STATE, DRIVERS>;
|
|
349
947
|
dispose: () => void;
|
|
350
948
|
hmr: (newComponent?: AnyComponentModule<RootComponent<STATE, DRIVERS>>, state?: STATE) => void;
|
|
351
949
|
}
|
|
352
950
|
|
|
353
|
-
|
|
951
|
+
type HotModuleAPI = {
|
|
354
952
|
accept: (...args: any[]) => any;
|
|
355
953
|
dispose?: (callback: () => void) => void;
|
|
356
954
|
}
|
|
357
955
|
|
|
358
|
-
|
|
956
|
+
declare function run<
|
|
359
957
|
STATE = any,
|
|
360
958
|
DRIVERS = {},
|
|
361
959
|
ACTIONS = {},
|
|
@@ -367,21 +965,21 @@ export function run<
|
|
|
367
965
|
options?: RunOptions
|
|
368
966
|
): SygnalApp<STATE & CALCULATED, FixDrivers<DRIVERS>>
|
|
369
967
|
|
|
370
|
-
|
|
968
|
+
declare function run(
|
|
371
969
|
component: any,
|
|
372
970
|
drivers?: Record<string, CycleDriver<any, any>>,
|
|
373
971
|
options?: RunOptions
|
|
374
972
|
): SygnalApp<any, {}>
|
|
375
973
|
|
|
376
|
-
|
|
974
|
+
declare function enableHMR<STATE = any, DRIVERS = {}>(
|
|
377
975
|
app: SygnalApp<STATE, DRIVERS>,
|
|
378
976
|
hot: HotModuleAPI,
|
|
379
977
|
loadComponent?: () => Promise<AnyComponentModule<RootComponent<STATE, DRIVERS>>> | AnyComponentModule<RootComponent<STATE, DRIVERS>>,
|
|
380
978
|
acceptDependencies?: string | string[]
|
|
381
979
|
): SygnalApp<STATE, DRIVERS>
|
|
382
980
|
|
|
383
|
-
|
|
384
|
-
|
|
981
|
+
declare function classes(...classes: ClassesType): string
|
|
982
|
+
declare function exactState<STATE>(): <ACTUAL extends STATE>(state: ExactShape<STATE, ACTUAL>) => STATE
|
|
385
983
|
|
|
386
984
|
// ── Reducer helpers ────────────────────────────────────────────────
|
|
387
985
|
|
|
@@ -395,7 +993,7 @@ export function exactState<STATE>(): <ACTUAL extends STATE>(state: ExactShape<ST
|
|
|
395
993
|
* returns the partial update to merge:
|
|
396
994
|
* `set((state, title) => ({ title }))`
|
|
397
995
|
*/
|
|
398
|
-
|
|
996
|
+
declare function set<S = any>(
|
|
399
997
|
partial: Partial<S> | ((state: S, data: any, next: Function, props: any) => Partial<S>)
|
|
400
998
|
): (state: S, data: any, next: Function, props: any) => S
|
|
401
999
|
|
|
@@ -404,33 +1002,69 @@ export function set<S = any>(
|
|
|
404
1002
|
*
|
|
405
1003
|
* `toggle('showModal')`
|
|
406
1004
|
*/
|
|
407
|
-
|
|
1005
|
+
declare function toggle<S = any>(field: keyof S & string): (state: S) => S
|
|
1006
|
+
|
|
1007
|
+
type EmitEntry<TYPE extends string> = keyof SygnalEvents extends never
|
|
1008
|
+
? { EVENTS: (state: any, actionData: any, next: Function, props: any) => { type: string; data: any } }
|
|
1009
|
+
: { EVENTS: (state: any, actionData: any, next: Function, props: any) => EmittedEvent<TYPE> }
|
|
408
1010
|
|
|
409
1011
|
/**
|
|
410
1012
|
* Create a model entry that emits an EVENTS bus event.
|
|
1013
|
+
* Prefer `event()` inside the object form: `ACTION: { EVENTS: event('TYPE', fn) }`.
|
|
411
1014
|
*
|
|
412
1015
|
* `emit('DELETE_LANE', (state) => ({ laneId: state.id }))`
|
|
413
1016
|
* `emit('REFRESH')`
|
|
1017
|
+
*
|
|
1018
|
+
* With a `SygnalEvents` registry, `type` and the payload are checked against it.
|
|
1019
|
+
*/
|
|
1020
|
+
declare function emit<TYPE extends EventName>(
|
|
1021
|
+
type: TYPE,
|
|
1022
|
+
data: (state: any, actionData: any, next: Function, props: any) => EventPayload<TYPE>
|
|
1023
|
+
): EmitEntry<TYPE>
|
|
1024
|
+
declare function emit<TYPE extends EventName>(
|
|
1025
|
+
type: TYPE,
|
|
1026
|
+
...data: StaticEventArgs<TYPE>
|
|
1027
|
+
): EmitEntry<TYPE>
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* Create an EVENTS sink function that puts `{ type, data }` on the EVENTS bus.
|
|
1031
|
+
* Use it as the `EVENTS` value inside an object-form model entry:
|
|
1032
|
+
*
|
|
1033
|
+
* DELETE: {
|
|
1034
|
+
* STATE: (state) => ({ ...state, deleting: true }),
|
|
1035
|
+
* EVENTS: event('DELETE_LANE', (state) => ({ laneId: state.id })),
|
|
1036
|
+
* }
|
|
1037
|
+
*
|
|
1038
|
+
* The payload is either a function `(state, data, next, props) => payload` or a static value:
|
|
1039
|
+
* `event('RESET')`, `event('SET_MODE', 'dark')`.
|
|
1040
|
+
*
|
|
1041
|
+
* With a `SygnalEvents` registry, `type` must be a registered name and the payload must match
|
|
1042
|
+
* its type. When used inside a model, the payload function's `state` and `data` parameters are
|
|
1043
|
+
* typed from the component.
|
|
414
1044
|
*/
|
|
415
|
-
|
|
416
|
-
type:
|
|
417
|
-
|
|
418
|
-
):
|
|
1045
|
+
declare function event<TYPE extends EventName, STATE = any, DATA = any>(
|
|
1046
|
+
type: TYPE,
|
|
1047
|
+
payload: EventPayloadFunction<TYPE, STATE, DATA>
|
|
1048
|
+
): EventSink<TYPE, STATE, DATA>
|
|
1049
|
+
declare function event<TYPE extends EventName>(
|
|
1050
|
+
type: TYPE,
|
|
1051
|
+
...payload: StaticEventArgs<TYPE>
|
|
1052
|
+
): EventSink<TYPE>
|
|
419
1053
|
|
|
420
1054
|
/**
|
|
421
1055
|
* Any object with an events() method (e.g., DOM.select('form')).
|
|
422
1056
|
* Uses permissive signature to be compatible with MainDOMSource's overloaded events().
|
|
423
1057
|
*/
|
|
424
|
-
|
|
1058
|
+
type FormSource = {
|
|
425
1059
|
events(eventName: string, ...args: any[]): Stream<any>
|
|
426
1060
|
}
|
|
427
1061
|
|
|
428
|
-
|
|
1062
|
+
type FormData<FIELDS extends Record<string, string> = Record<string, string>> = FIELDS & {
|
|
429
1063
|
event: globalThis.Event;
|
|
430
1064
|
eventType: string;
|
|
431
1065
|
}
|
|
432
1066
|
|
|
433
|
-
|
|
1067
|
+
type ProcessFormOptions = {
|
|
434
1068
|
events?: string | string[];
|
|
435
1069
|
preventDefault?: boolean;
|
|
436
1070
|
}
|
|
@@ -449,7 +1083,7 @@ export type ProcessFormOptions = {
|
|
|
449
1083
|
* // form$ is Stream<FormData<{ username: string; email: string }>>
|
|
450
1084
|
* // form$.username is typed as string ✓
|
|
451
1085
|
*/
|
|
452
|
-
|
|
1086
|
+
declare function processForm<FIELDS extends Record<string, string> = Record<string, string>>(
|
|
453
1087
|
target: FormSource,
|
|
454
1088
|
options?: ProcessFormOptions
|
|
455
1089
|
): Stream<FormData<FIELDS>>
|
|
@@ -458,11 +1092,11 @@ export function processForm<FIELDS extends Record<string, string> = Record<strin
|
|
|
458
1092
|
* Any object with an events() method (e.g., DOM.select('.draggable')).
|
|
459
1093
|
* Uses permissive signature to be compatible with MainDOMSource's overloaded events().
|
|
460
1094
|
*/
|
|
461
|
-
|
|
1095
|
+
type DragSource = {
|
|
462
1096
|
events(eventName: string, ...args: any[]): Stream<any>
|
|
463
1097
|
}
|
|
464
1098
|
|
|
465
|
-
|
|
1099
|
+
declare function processDrag(
|
|
466
1100
|
sources?: { draggable?: DragSource; dropZone?: DragSource },
|
|
467
1101
|
options?: { effectAllowed?: string }
|
|
468
1102
|
): {
|
|
@@ -472,7 +1106,7 @@ export function processDrag(
|
|
|
472
1106
|
drop$: Stream<DragEvent>
|
|
473
1107
|
}
|
|
474
1108
|
|
|
475
|
-
|
|
1109
|
+
type DragDriverRegistration = {
|
|
476
1110
|
category: string;
|
|
477
1111
|
draggable?: string;
|
|
478
1112
|
dropZone?: string;
|
|
@@ -482,24 +1116,24 @@ export type DragDriverRegistration = {
|
|
|
482
1116
|
dragImage?: string;
|
|
483
1117
|
}
|
|
484
1118
|
|
|
485
|
-
|
|
1119
|
+
type DragStartPayload = {
|
|
486
1120
|
element: HTMLElement;
|
|
487
1121
|
dataset: Record<string, string>;
|
|
488
1122
|
}
|
|
489
1123
|
|
|
490
|
-
|
|
1124
|
+
type DropPayload = {
|
|
491
1125
|
dropZone: HTMLElement;
|
|
492
1126
|
insertBefore: HTMLElement | null;
|
|
493
1127
|
}
|
|
494
1128
|
|
|
495
|
-
|
|
1129
|
+
type DragDriverCategory = {
|
|
496
1130
|
events(eventType: 'dragstart'): Stream<DragStartPayload>;
|
|
497
1131
|
events(eventType: 'dragend'): Stream<null>;
|
|
498
1132
|
events(eventType: 'drop'): Stream<DropPayload>;
|
|
499
1133
|
events(eventType: string): Stream<any>;
|
|
500
1134
|
}
|
|
501
1135
|
|
|
502
|
-
|
|
1136
|
+
type DragDriverSource = {
|
|
503
1137
|
select(category: string): DragDriverCategory;
|
|
504
1138
|
dragstart(category: string): Stream<DragStartPayload>;
|
|
505
1139
|
dragend(category: string): Stream<null>;
|
|
@@ -508,9 +1142,9 @@ export type DragDriverSource = {
|
|
|
508
1142
|
dispose(): void;
|
|
509
1143
|
}
|
|
510
1144
|
|
|
511
|
-
|
|
1145
|
+
declare function makeDragDriver(): (sink$: Stream<DragDriverRegistration | DragDriverRegistration[]>) => DragDriverSource
|
|
512
1146
|
|
|
513
|
-
|
|
1147
|
+
type ComponentFactoryOptions<
|
|
514
1148
|
STATE = any,
|
|
515
1149
|
PROPS = any,
|
|
516
1150
|
DRIVERS = {},
|
|
@@ -536,7 +1170,7 @@ export type ComponentFactoryOptions<
|
|
|
536
1170
|
debug?: boolean;
|
|
537
1171
|
}
|
|
538
1172
|
|
|
539
|
-
|
|
1173
|
+
declare function component<
|
|
540
1174
|
STATE = any,
|
|
541
1175
|
PROPS = any,
|
|
542
1176
|
DRIVERS = {},
|
|
@@ -548,25 +1182,50 @@ export function component<
|
|
|
548
1182
|
options: ComponentFactoryOptions<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, CONTEXT, SINK_RETURNS>
|
|
549
1183
|
): Component<STATE, PROPS, DRIVERS, ACTIONS, CALCULATED, CONTEXT, SINK_RETURNS>
|
|
550
1184
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
1185
|
+
declare function collection(...args: any[]): any
|
|
1186
|
+
declare function switchable(...args: any[]): any
|
|
1187
|
+
declare function portal(...args: any[]): any
|
|
554
1188
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
1189
|
+
declare function Collection<PROPS extends { [prop: string]: any }, STATE = any>(props: CollectionProps<PROPS, STATE>): JSX.Element
|
|
1190
|
+
declare function Switchable<PROPS extends { [prop: string]: any }>(props: SwitchableProps<PROPS>): JSX.Element
|
|
1191
|
+
declare function Portal(props: PortalProps): JSX.Element
|
|
1192
|
+
declare function Transition(props: TransitionProps): JSX.Element
|
|
1193
|
+
declare function Suspense(props: SuspenseProps): JSX.Element
|
|
1194
|
+
declare function Slot(props: SlotProps): JSX.Element
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* What `lazy()` returns: a sub-component used in JSX with its own props only
|
|
1198
|
+
* (`<Chart title="Sales" />`; `state` is optional, as for any sub-component), that
|
|
1199
|
+
* still carries the component statics (`model`, `intent`, …) once loaded.
|
|
1200
|
+
*/
|
|
1201
|
+
type LazyComponent<PROPS = any> = ((
|
|
1202
|
+
props: PROPS & { state?: any; children?: JSX.Element | JSX.Element[] }
|
|
1203
|
+
) => JSX.Element) & Omit<Component<any, PROPS>, never>
|
|
560
1204
|
|
|
561
|
-
|
|
1205
|
+
declare function lazy<PROPS = any>(
|
|
562
1206
|
loadFn: () => Promise<{ default: Component<any, PROPS> } | Component<any, PROPS>>
|
|
563
|
-
):
|
|
1207
|
+
): LazyComponent<PROPS>
|
|
1208
|
+
|
|
1209
|
+
/** Payload on `errors()` of a driverFromAsync source when a request fails */
|
|
1210
|
+
type AsyncDriverError<INCOMING = any> = {
|
|
1211
|
+
/** The rejection reason (or what `post` threw) */
|
|
1212
|
+
error: any;
|
|
1213
|
+
/** The request that failed */
|
|
1214
|
+
request: INCOMING;
|
|
1215
|
+
/** The request's selector property (default 'category') is copied here */
|
|
1216
|
+
[selectorProperty: string]: any;
|
|
1217
|
+
}
|
|
564
1218
|
|
|
565
|
-
|
|
1219
|
+
type AsyncDriverFromFunction<INCOMING = any, OUTGOING = any> = {
|
|
566
1220
|
select: (selector?: string | ((value: OUTGOING) => boolean)) => Stream<OUTGOING>
|
|
1221
|
+
/**
|
|
1222
|
+
* Failed requests (rejected promise, rejected/throwing `post`). Filters like
|
|
1223
|
+
* `select()`. Failures are only console.error'd while nothing listens here.
|
|
1224
|
+
*/
|
|
1225
|
+
errors: (selector?: string | ((error: AsyncDriverError<INCOMING>) => boolean)) => Stream<AsyncDriverError<INCOMING>>
|
|
567
1226
|
}
|
|
568
1227
|
|
|
569
|
-
|
|
1228
|
+
type DriverFromAsyncOptions<INCOMING = any, OUTGOING = any, RETURN = any> = {
|
|
570
1229
|
selector?: string;
|
|
571
1230
|
args?: string | string[] | ((incoming: INCOMING) => any | any[]);
|
|
572
1231
|
return?: string | undefined;
|
|
@@ -574,71 +1233,101 @@ export type DriverFromAsyncOptions<INCOMING = any, OUTGOING = any, RETURN = any>
|
|
|
574
1233
|
post?: (value: RETURN, incoming: INCOMING) => OUTGOING | Promise<OUTGOING>;
|
|
575
1234
|
}
|
|
576
1235
|
|
|
577
|
-
|
|
1236
|
+
declare function driverFromAsync<INCOMING = any, RETURN = any, OUTGOING = any>(
|
|
578
1237
|
promiseReturningFunction: (...args: any[]) => Promise<RETURN>,
|
|
579
1238
|
options?: DriverFromAsyncOptions<INCOMING, OUTGOING, RETURN>
|
|
580
1239
|
): (fromApp$: Stream<INCOMING>) => AsyncDriverFromFunction<INCOMING, OUTGOING>
|
|
581
1240
|
|
|
582
|
-
|
|
1241
|
+
interface Ref<T = HTMLElement> {
|
|
583
1242
|
current: T | null;
|
|
584
1243
|
}
|
|
585
1244
|
|
|
586
|
-
|
|
1245
|
+
interface Ref$<T = HTMLElement> extends Ref<T> {
|
|
587
1246
|
stream: MemoryStream<T | null>;
|
|
588
1247
|
}
|
|
589
1248
|
|
|
590
|
-
|
|
591
|
-
|
|
1249
|
+
declare function createRef<T = HTMLElement>(): Ref<T>
|
|
1250
|
+
declare function createRef$<T = HTMLElement>(): Ref$<T>
|
|
592
1251
|
|
|
593
|
-
|
|
1252
|
+
interface Command {
|
|
594
1253
|
send(type: string, data?: any): void;
|
|
595
1254
|
}
|
|
596
1255
|
|
|
597
|
-
|
|
1256
|
+
interface CommandSource {
|
|
598
1257
|
select(type: string): Stream<any>;
|
|
599
1258
|
}
|
|
600
1259
|
|
|
601
|
-
|
|
1260
|
+
declare function createCommand(): Command
|
|
602
1261
|
|
|
603
1262
|
// ── PWA Helpers ──────────────────────────────────────────────
|
|
604
1263
|
|
|
605
|
-
|
|
1264
|
+
interface ServiceWorkerSource {
|
|
606
1265
|
select(type?: 'installed' | 'activated' | 'waiting' | 'controlling' | 'error' | 'message' | string): Stream<any>;
|
|
607
1266
|
}
|
|
608
1267
|
|
|
609
|
-
|
|
1268
|
+
interface ServiceWorkerCommand {
|
|
610
1269
|
action: 'skipWaiting' | 'postMessage' | 'unregister';
|
|
611
1270
|
data?: any;
|
|
612
1271
|
}
|
|
613
1272
|
|
|
614
|
-
|
|
1273
|
+
interface ServiceWorkerOptions {
|
|
615
1274
|
scope?: string;
|
|
616
1275
|
}
|
|
617
1276
|
|
|
618
|
-
|
|
1277
|
+
declare function makeServiceWorkerDriver(
|
|
619
1278
|
scriptUrl: string,
|
|
620
1279
|
options?: ServiceWorkerOptions
|
|
621
1280
|
): (sink$: Stream<ServiceWorkerCommand>) => ServiceWorkerSource
|
|
622
1281
|
|
|
623
|
-
|
|
1282
|
+
declare const onlineStatus$: Stream<boolean>
|
|
624
1283
|
|
|
625
|
-
|
|
1284
|
+
interface InstallPrompt {
|
|
626
1285
|
select(type: 'beforeinstallprompt' | 'appinstalled'): Stream<any>;
|
|
627
1286
|
prompt(): Promise<any> | undefined;
|
|
628
1287
|
}
|
|
629
1288
|
|
|
630
|
-
|
|
1289
|
+
declare function createInstallPrompt(): InstallPrompt
|
|
1290
|
+
|
|
1291
|
+
interface SimulatedEventInit {
|
|
1292
|
+
/** Merged into `event.target` (value, checked, dataset, ...) */
|
|
1293
|
+
target?: Record<string, any>;
|
|
1294
|
+
/** Shorthand for target.value */
|
|
1295
|
+
value?: any;
|
|
1296
|
+
/** Shorthand for target.checked */
|
|
1297
|
+
checked?: boolean;
|
|
1298
|
+
/** Merged into target.dataset (values become strings, like the DOM) */
|
|
1299
|
+
dataset?: Record<string, any>;
|
|
1300
|
+
/** Alias for dataset */
|
|
1301
|
+
data?: Record<string, any>;
|
|
1302
|
+
/** Keyboard key (e.key) */
|
|
1303
|
+
key?: string;
|
|
1304
|
+
/**
|
|
1305
|
+
* Don't fail when the selector matches no rendered element: wait up to 300ms for it, then
|
|
1306
|
+
* drop the event with SYG103 (info). Not copied onto the event.
|
|
1307
|
+
*/
|
|
1308
|
+
allowMissing?: boolean;
|
|
1309
|
+
/** Any other event properties are copied onto the event */
|
|
1310
|
+
[prop: string]: any;
|
|
1311
|
+
}
|
|
631
1312
|
|
|
632
|
-
|
|
1313
|
+
interface RenderOptions {
|
|
633
1314
|
/** Override initial state (defaults to component's .initialState) */
|
|
634
1315
|
initialState?: any;
|
|
635
1316
|
/** Mock DOM configuration — maps selectors to event streams */
|
|
636
1317
|
mockConfig?: Record<string, any>;
|
|
637
|
-
/** Additional drivers beyond DOM, EVENTS, STATE, and LOG */
|
|
1318
|
+
/** Additional drivers beyond DOM, EVENTS, STATE, and LOG (model sinks without a driver get a no-op one) */
|
|
638
1319
|
drivers?: Record<string, any>;
|
|
1320
|
+
/**
|
|
1321
|
+
* Diagnostics mode while rendered. Default: 'collect' (error-severity messages still print),
|
|
1322
|
+
* or the current mode when diagnostics are already on. Restored when the last instance is
|
|
1323
|
+
* disposed. Dev checks require `import 'sygnal/diagnostics'` (the Vite plugin adds it under Vitest).
|
|
1324
|
+
*/
|
|
1325
|
+
diagnostics?: DiagnosticsMode;
|
|
1326
|
+
/** Enable strict (canonical-form) runtime checks while rendered (requires 'sygnal/diagnostics') */
|
|
1327
|
+
strict?: boolean;
|
|
639
1328
|
}
|
|
640
1329
|
|
|
641
|
-
|
|
1330
|
+
interface RenderResult {
|
|
642
1331
|
/** Stream of state values */
|
|
643
1332
|
state$: Stream<any>;
|
|
644
1333
|
/** Stream of rendered VNode trees */
|
|
@@ -649,19 +1338,73 @@ export interface RenderResult {
|
|
|
649
1338
|
sinks: Record<string, any>;
|
|
650
1339
|
/** All source objects by driver name */
|
|
651
1340
|
sources: Record<string, any>;
|
|
652
|
-
/** Push an action
|
|
1341
|
+
/** Push an action into the intent→model pipeline under its real name (all sinks of the entry run) */
|
|
653
1342
|
simulateAction: (actionName: string, data?: any) => void;
|
|
654
|
-
/**
|
|
1343
|
+
/**
|
|
1344
|
+
* Dispatch a synthetic DOM event through the mock DOM source so the component's real intent
|
|
1345
|
+
* streams fire (DOM.click('.x'), DOM.select('.x').events('click'), .value(), .data()).
|
|
1346
|
+
* Targets the first rendered element matching `selector` and bubbles within its isolation scope.
|
|
1347
|
+
* Selectors match the rendered tree like the real DOM: tag, .class, #id, [attr], [attr="v"]
|
|
1348
|
+
* (^= $= *= ~=), :first-child, :last-child, :only-child, :nth-child(an+b|odd|even),
|
|
1349
|
+
* :nth-last-child(), :first/last/only/nth-of-type, :not(), descendant ' ' and child '>'
|
|
1350
|
+
* combinators, ',' lists. Other syntax (:has(), '+', '~', pseudo-elements...) throws.
|
|
1351
|
+
* If nothing matches yet, the event waits (up to 300ms, re-checked on every render) for a
|
|
1352
|
+
* matching element, then targets the first one. If none renders, the test fails with an
|
|
1353
|
+
* error naming the selector: it rejects the pending next()/waitForState()/settle(), or is
|
|
1354
|
+
* thrown by the next t.* call or dispose() (or by simulateEvent itself when nothing is
|
|
1355
|
+
* pending and the tree is quiet). Pass `{ allowMissing: true }` to drop the event with SYG103
|
|
1356
|
+
* instead. It is never sent to every listener with that selector string. It also waits until
|
|
1357
|
+
* the listeners it reaches are subscribed (a just-mounted child subscribes a few ms late).
|
|
1358
|
+
* `'document'` / `'body'` go to the DOM.select('document' | 'body') listeners.
|
|
1359
|
+
* simulateAction/simulateEvent calls are delivered in call order; a waiting event holds the
|
|
1360
|
+
* calls after it. Reports SYG104 (selector only matches inside a child component).
|
|
1361
|
+
*/
|
|
1362
|
+
simulateEvent: (selector: string, eventType: string, eventInit?: SimulatedEventInit) => void;
|
|
1363
|
+
/** Resolves once the component is subscribed (earlier simulate* calls are buffered and replayed) */
|
|
1364
|
+
ready: () => Promise<void>;
|
|
1365
|
+
/**
|
|
1366
|
+
* Wait for a state that satisfies the predicate. Matches the recorded HISTORY too: a state
|
|
1367
|
+
* from before the call resolves it (e.g. `count === 0` right after a reset resolves at once
|
|
1368
|
+
* with the initial state). Resolves with the matching state once the whole tree (children
|
|
1369
|
+
* included) has rendered it. Use `next()` to wait for a new state.
|
|
1370
|
+
*/
|
|
655
1371
|
waitForState: (predicate: (state: any) => boolean, timeoutMs?: number) => Promise<any>;
|
|
1372
|
+
/**
|
|
1373
|
+
* Wait for the next state emitted AFTER this call that satisfies the predicate (default: any
|
|
1374
|
+
* state). Resolves with it once the whole tree (children included) has rendered it; rejects
|
|
1375
|
+
* after timeoutMs (default 2000).
|
|
1376
|
+
*/
|
|
1377
|
+
next: (predicate?: (state: any) => boolean, timeoutMs?: number) => Promise<any>;
|
|
1378
|
+
/**
|
|
1379
|
+
* Resolves once nothing is pending: the component is ready, no simulated input is waiting,
|
|
1380
|
+
* and nothing in the tree has rendered, reduced or changed state for 20ms (longer than
|
|
1381
|
+
* next()'s default delay). Rejects after timeoutMs (default 2000) if it never calms down.
|
|
1382
|
+
*/
|
|
1383
|
+
settle: (timeoutMs?: number) => Promise<void>;
|
|
656
1384
|
/** Collected state values — grows as new states are emitted */
|
|
657
1385
|
states: any[];
|
|
658
|
-
/**
|
|
1386
|
+
/** Live array of values emitted on a sink (EVENTS as {type, data}, PARENT unwrapped, custom drivers) */
|
|
1387
|
+
sinkValues: (sinkName: string) => any[];
|
|
1388
|
+
/** Live array of EVENTS sink emissions ({type, data}) */
|
|
1389
|
+
emitted: Array<{ type: string; data: any }>;
|
|
1390
|
+
/** Live array of diagnostics reported while rendered */
|
|
1391
|
+
diagnostics: Diagnostic[];
|
|
1392
|
+
/** Throws (with the formatted texts) if any warn/error diagnostics were collected */
|
|
1393
|
+
expectNoDiagnostics: () => void;
|
|
1394
|
+
/** Latest rendered VNode serialized to HTML ('' before the first render) */
|
|
1395
|
+
html: () => string;
|
|
1396
|
+
/** Tear down the component, clean up listeners and restore the diagnostics mode */
|
|
659
1397
|
dispose: () => void;
|
|
1398
|
+
/**
|
|
1399
|
+
* The app graph of the rendered tree (components, actions, selectors with the mock DOM's
|
|
1400
|
+
* match / isolation results, EVENTS, diagnostics). Throws unless 'sygnal/diagnostics' is loaded.
|
|
1401
|
+
*/
|
|
1402
|
+
inspect: () => InspectGraph;
|
|
660
1403
|
}
|
|
661
1404
|
|
|
662
|
-
|
|
1405
|
+
declare function renderComponent(componentDef: any, options?: RenderOptions): RenderResult
|
|
663
1406
|
|
|
664
|
-
|
|
1407
|
+
interface RenderToStringOptions {
|
|
665
1408
|
/** Initial state for the root component */
|
|
666
1409
|
state?: any
|
|
667
1410
|
/** Props to pass to the root component */
|
|
@@ -679,18 +1422,10 @@ export interface RenderToStringOptions {
|
|
|
679
1422
|
/**
|
|
680
1423
|
* Render a Sygnal component to an HTML string on the server.
|
|
681
1424
|
*/
|
|
682
|
-
|
|
1425
|
+
declare function renderToString(componentDef: any, options?: RenderToStringOptions): string
|
|
683
1426
|
|
|
684
|
-
|
|
1427
|
+
declare const xs: typeof xsDefault
|
|
685
1428
|
|
|
686
|
-
export { default as debounce } from 'xstream/extra/debounce.js'
|
|
687
|
-
export { default as throttle } from 'xstream/extra/throttle.js'
|
|
688
|
-
export { default as delay } from 'xstream/extra/delay.js'
|
|
689
|
-
export { default as dropRepeats } from 'xstream/extra/dropRepeats.js'
|
|
690
|
-
export { default as sampleCombine } from 'xstream/extra/sampleCombine.js'
|
|
691
|
-
|
|
692
|
-
export * from './cycle/dom/index'
|
|
693
|
-
export type { MemoryStream, Stream }
|
|
694
1429
|
|
|
695
1430
|
/**
|
|
696
1431
|
* JSX Types
|
|
@@ -717,3 +1452,5 @@ declare global {
|
|
|
717
1452
|
}
|
|
718
1453
|
}
|
|
719
1454
|
}
|
|
1455
|
+
|
|
1456
|
+
export { ABORT, type ActionsOf, type AnyComponentModule, type ArrayKeysOf, type AsyncDriverError, type AsyncDriverFromFunction, type ClassesType, Collection, type CollectionFrom, type CollectionProps, type Command, type CommandSource, type Component, type ComponentFactoryOptions, type CycleDOMEvent, type CycleDriver, type DOMDriverOptions, type DOMSource, type DefaultDrivers, type Diagnostic, type DiagnosticCode, type DiagnosticSeverity, type DiagnosticsMode, type DiagnosticsOptions, type DragDriverCategory, type DragDriverRegistration, type DragDriverSource, type DragSource, type DragStartPayload, type DriverFactories, type DriverFromAsyncOptions, type DriverSpec, type DriverSpecs, type DropPayload, type EmittedEvent, type EnrichedEventStream, type Event$1 as Event, type EventName, type EventPayload, type EventPayloadFunction, type EventSink, type EventsFnOptions, type EventsSource, type ExactShape, type Filter, type FixDrivers, type FormData, type FormSource, type HotModuleAPI, type InspectAction, type InspectActionTrigger, type InspectChild, type InspectComponent, type InspectDiagnostic, type InspectGraph, type InspectSelector, type InstallPrompt, type IntentSources, type LazyComponent, type Lens, type Lense, MainDOMSource, type MockConfig, MockedDOMSource, type NonStateSinkReturns, type ParentPayloadOf, Portal, type PortalProps, type ProcessFormOptions, type Ref, type Ref$, type RegisteredEvent, type RenderOptions, type RenderResult, type RenderToStringOptions, type RootComponent, type RunOptions, type ServiceWorkerCommand, type ServiceWorkerOptions, type ServiceWorkerSource, type SimulatedEventInit, Slot, type SlotProps, type SortFunction, type SortObject, Suspense, type SuspenseProps, Switchable, type SwitchableProps, type SygnalApp, type SygnalDOMSource, type SygnalDevTools, type SygnalEvents, type SygnalSinks, type Thunk, type ThunkData, Transition, type TransitionProps, classes, clearDiagnostics, collection, component, createCommand, createInstallPrompt, createRef, createRef$, driverFromAsync, emit, enableHMR, event, exactState, getDevTools, getDiagnostics, lazy, makeDOMDriver, makeDragDriver, makeServiceWorkerDriver, mockDOMSource, onDiagnostic, onlineStatus$, portal, processDrag, processForm, renderComponent, renderToString, run, set, switchable, thunk, toggle, xs };
|