@torpor/view 0.4.18 → 1.0.1
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 +41 -16
- package/dist/Cleanup-D0wvGW5d.d.cts +9 -0
- package/dist/Cleanup-D0wvGW5d.d.cts.map +1 -0
- package/dist/Cleanup-D0wvGW5d.d.mts +9 -0
- package/dist/Cleanup-D0wvGW5d.d.mts.map +1 -0
- package/dist/Component-0MH0zd-m.d.cts +11 -0
- package/dist/Component-0MH0zd-m.d.cts.map +1 -0
- package/dist/Component-0MH0zd-m.d.mts +11 -0
- package/dist/Component-0MH0zd-m.d.mts.map +1 -0
- package/dist/Effect-BTKurOpr.d.mts +381 -0
- package/dist/Effect-BTKurOpr.d.mts.map +1 -0
- package/dist/Effect-COl3aRJV.d.cts +381 -0
- package/dist/Effect-COl3aRJV.d.cts.map +1 -0
- package/dist/compile.cjs +1734 -739
- package/dist/compile.d.cts +85 -50
- package/dist/compile.d.cts.map +1 -1
- package/dist/compile.d.mts +85 -50
- package/dist/compile.d.mts.map +1 -1
- package/dist/compile.mjs +1737 -741
- package/dist/compile.mjs.map +1 -1
- package/dist/dev.cjs +62 -63
- package/dist/dev.d.cts +4 -3
- package/dist/dev.d.cts.map +1 -1
- package/dist/dev.d.mts +4 -3
- package/dist/dev.d.mts.map +1 -1
- package/dist/dev.mjs +61 -62
- package/dist/dev.mjs.map +1 -1
- package/dist/{devContext-B3yskfhA.cjs → devContext-BulTn3U5.cjs} +6 -9
- package/dist/{devContext-CQ8RhBX-.mjs → devContext-ZNsPyOgB.mjs} +3 -4
- package/dist/devContext-ZNsPyOgB.mjs.map +1 -0
- package/dist/fromWebSocket-1QOjcrHE.cjs +182 -0
- package/dist/fromWebSocket-B52kN3-W.d.mts +91 -0
- package/dist/fromWebSocket-B52kN3-W.d.mts.map +1 -0
- package/dist/fromWebSocket-DeB35Q4w.d.cts +91 -0
- package/dist/fromWebSocket-DeB35Q4w.d.cts.map +1 -0
- package/dist/fromWebSocket-Dxc_uwm1.mjs +137 -0
- package/dist/fromWebSocket-Dxc_uwm1.mjs.map +1 -0
- package/dist/index.cjs +2109 -494
- package/dist/index.d.cts +608 -112
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +608 -112
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2088 -490
- package/dist/index.mjs.map +1 -1
- package/dist/ssr.cjs +78 -17
- package/dist/ssr.d.cts +64 -11
- package/dist/ssr.d.cts.map +1 -1
- package/dist/ssr.d.mts +64 -11
- package/dist/ssr.d.mts.map +1 -1
- package/dist/ssr.mjs +67 -14
- package/dist/ssr.mjs.map +1 -1
- package/package.json +21 -19
- package/dist/Cleanup-CYsytTEc.d.cts +0 -9
- package/dist/Cleanup-CYsytTEc.d.cts.map +0 -1
- package/dist/Cleanup-CgjyN0lW.d.mts +0 -9
- package/dist/Cleanup-CgjyN0lW.d.mts.map +0 -1
- package/dist/Component-DmWGMgak.d.mts +0 -11
- package/dist/Component-DmWGMgak.d.mts.map +0 -1
- package/dist/Component-kGLRFYg2.d.cts +0 -11
- package/dist/Component-kGLRFYg2.d.cts.map +0 -1
- package/dist/Region-Bb6HAb-F.d.cts +0 -201
- package/dist/Region-Bb6HAb-F.d.cts.map +0 -1
- package/dist/Region-CTchywkr.d.mts +0 -201
- package/dist/Region-CTchywkr.d.mts.map +0 -1
- package/dist/devContext-CQ8RhBX-.mjs.map +0 -1
- package/dist/formatText-BNP3P38F.d.cts +0 -17
- package/dist/formatText-BNP3P38F.d.cts.map +0 -1
- package/dist/formatText-D6Ov8Ub0.d.mts +0 -17
- package/dist/formatText-D6Ov8Ub0.d.mts.map +0 -1
- package/dist/formatText-DTIRmc3X.mjs +0 -61
- package/dist/formatText-DTIRmc3X.mjs.map +0 -1
- package/dist/formatText-Dhl2O0Ee.cjs +0 -96
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
//#region src/watch/symbols.ts
|
|
2
|
+
const proxyDataSymbol = Symbol.for("torp.ProxyData");
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region src/watch/$unwrap.ts
|
|
5
|
+
/**
|
|
6
|
+
* Returns the target object of a proxy
|
|
7
|
+
*
|
|
8
|
+
* @param object The proxy object
|
|
9
|
+
*/
|
|
10
|
+
function $unwrap(object) {
|
|
11
|
+
return object !== void 0 && object !== null && object[proxyDataSymbol] !== void 0 ? object[proxyDataSymbol].target ?? object : object;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/render/buildClasses.ts
|
|
15
|
+
function buildClasses(value, styleHash) {
|
|
16
|
+
if (typeof value === "string") {
|
|
17
|
+
if (styleHash !== void 0) value += " " + styleHash;
|
|
18
|
+
return value;
|
|
19
|
+
} else {
|
|
20
|
+
let classes = [];
|
|
21
|
+
gatherClasses("", value, classes);
|
|
22
|
+
if (styleHash !== void 0) classes.push(styleHash);
|
|
23
|
+
return classes.join(" ");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function gatherClasses(name, value, classes) {
|
|
27
|
+
if (value) {
|
|
28
|
+
value = $unwrap(value);
|
|
29
|
+
if (Array.isArray(value)) for (let v of value) gatherClasses(v, v, classes);
|
|
30
|
+
else if (typeof value === "object") for (const n in value) gatherClasses(n, value[n], classes);
|
|
31
|
+
else classes.push(name);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/render/buildStyles.ts
|
|
36
|
+
const CAMEL_TO_DASH = /[A-Z]+(?![a-z])|[A-Z]/g;
|
|
37
|
+
function buildStyles(value) {
|
|
38
|
+
if (typeof value === "string") return value;
|
|
39
|
+
else {
|
|
40
|
+
let styles = [];
|
|
41
|
+
gatherStyles(value, styles);
|
|
42
|
+
return styles.join("; ");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function gatherStyles(value, styles) {
|
|
46
|
+
if (value) if (Array.isArray(value)) for (let v of value) gatherStyles(v, styles);
|
|
47
|
+
else if (typeof value === "object") for (let [n, v] of Object.entries(value)) {
|
|
48
|
+
if (v === null || v === void 0) continue;
|
|
49
|
+
const key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? "-" : "") + char.toLowerCase());
|
|
50
|
+
styles.push(`${key}: ${v}`);
|
|
51
|
+
}
|
|
52
|
+
else styles.push(String(value));
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/render/formatText.ts
|
|
56
|
+
function formatText(value) {
|
|
57
|
+
if (value === void 0 || value === null) return "";
|
|
58
|
+
if (typeof value === "string") return value;
|
|
59
|
+
return String($unwrap(value));
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/stream/fromElement.ts
|
|
63
|
+
/**
|
|
64
|
+
* Creates a StreamSource that pushes DOM events of the given type from an
|
|
65
|
+
* element.
|
|
66
|
+
*
|
|
67
|
+
* ```torp
|
|
68
|
+
* $stream(fromElement(() => saveButton, "click"), (e) => {
|
|
69
|
+
* $state.clicks.push(e);
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
function fromElement(target, type) {
|
|
74
|
+
return (push) => {
|
|
75
|
+
const el = typeof target === "function" ? target() : target;
|
|
76
|
+
if (!el) throw new Error("fromElement: element not found. When passing a &ref variable, wrap it in a getter: fromElement(() => buttonEl, \"click\")");
|
|
77
|
+
const listener = push;
|
|
78
|
+
el.addEventListener(type, listener);
|
|
79
|
+
return () => {
|
|
80
|
+
el.removeEventListener(type, listener);
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/stream/fromServer.ts
|
|
86
|
+
/**
|
|
87
|
+
* Creates a StreamSource that receives `message` events from a server-sent
|
|
88
|
+
* events endpoint. The URL may be a getter, so reactive state can be read
|
|
89
|
+
* inside it — when it changes, the connection is closed and re-opened:
|
|
90
|
+
*
|
|
91
|
+
* ```torp
|
|
92
|
+
* $stream(fromServer(`/sse/${$props.id}`), (e) => {
|
|
93
|
+
* $state.messages.push(e.data);
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* Reconnection is handled by `EventSource` itself; errors are not pushed —
|
|
98
|
+
* a source that can fail should surface errors as values.
|
|
99
|
+
*/
|
|
100
|
+
function fromServer(url) {
|
|
101
|
+
return (push) => {
|
|
102
|
+
const eventSource = new EventSource(typeof url === "function" ? url() : url);
|
|
103
|
+
eventSource.onmessage = push;
|
|
104
|
+
return () => {
|
|
105
|
+
eventSource.close();
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/stream/fromWebSocket.ts
|
|
111
|
+
/**
|
|
112
|
+
* Creates a StreamSource that receives `message` events from a WebSocket.
|
|
113
|
+
* The URL may be a getter, so reactive state can be read inside it — when
|
|
114
|
+
* it changes, the socket is closed and re-opened:
|
|
115
|
+
*
|
|
116
|
+
* ```torp
|
|
117
|
+
* $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {
|
|
118
|
+
* $state.inbox.push(e.data);
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* Errors are not pushed — a source that can fail should surface errors as
|
|
123
|
+
* values and own its own reconnection.
|
|
124
|
+
*/
|
|
125
|
+
function fromWebSocket(url) {
|
|
126
|
+
return (push) => {
|
|
127
|
+
const socket = new WebSocket(typeof url === "function" ? url() : url);
|
|
128
|
+
socket.onmessage = push;
|
|
129
|
+
return () => {
|
|
130
|
+
socket.close();
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
Object.defineProperty(exports, "$unwrap", {
|
|
136
|
+
enumerable: true,
|
|
137
|
+
get: function() {
|
|
138
|
+
return $unwrap;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(exports, "buildClasses", {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function() {
|
|
144
|
+
return buildClasses;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
Object.defineProperty(exports, "buildStyles", {
|
|
148
|
+
enumerable: true,
|
|
149
|
+
get: function() {
|
|
150
|
+
return buildStyles;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(exports, "formatText", {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function() {
|
|
156
|
+
return formatText;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
Object.defineProperty(exports, "fromElement", {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
get: function() {
|
|
162
|
+
return fromElement;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
Object.defineProperty(exports, "fromServer", {
|
|
166
|
+
enumerable: true,
|
|
167
|
+
get: function() {
|
|
168
|
+
return fromServer;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
Object.defineProperty(exports, "fromWebSocket", {
|
|
172
|
+
enumerable: true,
|
|
173
|
+
get: function() {
|
|
174
|
+
return fromWebSocket;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
Object.defineProperty(exports, "proxyDataSymbol", {
|
|
178
|
+
enumerable: true,
|
|
179
|
+
get: function() {
|
|
180
|
+
return proxyDataSymbol;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { t as Cleanup } from "./Cleanup-D0wvGW5d.mjs";
|
|
2
|
+
//#region src/types/ClassValue.d.ts
|
|
3
|
+
type ClassValue = string | Record<string, boolean | null | undefined> | Array<ClassValue> | null | undefined;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/render/buildClasses.d.ts
|
|
6
|
+
declare function buildClasses(value: ClassValue, styleHash?: string): string;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/types/StyleValue.d.ts
|
|
9
|
+
type StyleValue = string | Record<string, string | null | undefined> | Array<StyleValue> | null | undefined;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/render/buildStyles.d.ts
|
|
12
|
+
declare function buildStyles(value: StyleValue): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/types/StreamSource.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* A subscription to an external source of events — server-sent events,
|
|
17
|
+
* WebSockets, DOM events, intervals, or anything else that pushes values
|
|
18
|
+
* over time.
|
|
19
|
+
*
|
|
20
|
+
* The function is called with a `push` callback when the stream is
|
|
21
|
+
* subscribed to (at mount time, and again whenever reactive state read
|
|
22
|
+
* inside it changes). It wires the external source up to `push` and returns
|
|
23
|
+
* a cleanup function that unsubscribes.
|
|
24
|
+
*
|
|
25
|
+
* Sources are never invoked during a server render, so browser-only APIs
|
|
26
|
+
* (`EventSource`, `WebSocket`, DOM elements) are safe to reference inside
|
|
27
|
+
* them.
|
|
28
|
+
*/
|
|
29
|
+
type StreamSource<T> = (push: (value: T) => void) => Cleanup | void;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/stream/fromElement.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* The element to listen on, or a getter returning it. Use a getter for
|
|
34
|
+
* `&ref`-bound variables — they are only assigned once the element is
|
|
35
|
+
* created, and subscriptions start at mount time:
|
|
36
|
+
*
|
|
37
|
+
* ```torp
|
|
38
|
+
* let saveButton: HTMLButtonElement;
|
|
39
|
+
*
|
|
40
|
+
* $stream(fromElement(() => saveButton, "click"), () => save());
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
type EventTargetInput = HTMLElement | (() => HTMLElement | null | undefined);
|
|
44
|
+
/**
|
|
45
|
+
* Creates a StreamSource that pushes DOM events of the given type from an
|
|
46
|
+
* element.
|
|
47
|
+
*
|
|
48
|
+
* ```torp
|
|
49
|
+
* $stream(fromElement(() => saveButton, "click"), (e) => {
|
|
50
|
+
* $state.clicks.push(e);
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
declare function fromElement<E extends Event = Event>(target: EventTargetInput, type: string): StreamSource<E>;
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/stream/fromServer.d.ts
|
|
57
|
+
/**
|
|
58
|
+
* Creates a StreamSource that receives `message` events from a server-sent
|
|
59
|
+
* events endpoint. The URL may be a getter, so reactive state can be read
|
|
60
|
+
* inside it — when it changes, the connection is closed and re-opened:
|
|
61
|
+
*
|
|
62
|
+
* ```torp
|
|
63
|
+
* $stream(fromServer(`/sse/${$props.id}`), (e) => {
|
|
64
|
+
* $state.messages.push(e.data);
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* Reconnection is handled by `EventSource` itself; errors are not pushed —
|
|
69
|
+
* a source that can fail should surface errors as values.
|
|
70
|
+
*/
|
|
71
|
+
declare function fromServer(url: string | (() => string)): StreamSource<MessageEvent>;
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/stream/fromWebSocket.d.ts
|
|
74
|
+
/**
|
|
75
|
+
* Creates a StreamSource that receives `message` events from a WebSocket.
|
|
76
|
+
* The URL may be a getter, so reactive state can be read inside it — when
|
|
77
|
+
* it changes, the socket is closed and re-opened:
|
|
78
|
+
*
|
|
79
|
+
* ```torp
|
|
80
|
+
* $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {
|
|
81
|
+
* $state.inbox.push(e.data);
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* Errors are not pushed — a source that can fail should surface errors as
|
|
86
|
+
* values and own its own reconnection.
|
|
87
|
+
*/
|
|
88
|
+
declare function fromWebSocket(url: string | (() => string)): StreamSource<MessageEvent>;
|
|
89
|
+
//#endregion
|
|
90
|
+
export { buildStyles as a, ClassValue as c, StreamSource as i, fromServer as n, StyleValue as o, fromElement as r, buildClasses as s, fromWebSocket as t };
|
|
91
|
+
//# sourceMappingURL=fromWebSocket-B52kN3-W.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fromWebSocket-B52kN3-W.d.mts","names":[],"sources":["../src/types/ClassValue.ts","../src/render/buildClasses.ts","../src/types/StyleValue.ts","../src/render/buildStyles.ts","../src/types/StreamSource.ts","../src/stream/fromElement.ts","../src/stream/fromServer.ts","../src/stream/fromWebSocket.ts"],"mappings":";;KAAK,sBAEF,6CACA,MAAM;;;iBCAe,aAAa,OAAO,YAAY;;;KCHnD,sBAEF,4CACA,MAAM;;;iBCCe,YAAY,OAAO;;;;;;;;;;;;;;;;;KCYtC,aAAa,MAAM,OAAO,OAAO,eAAe;;;;;;;;;;;;;;KCHhD,mBAAmB,qBAAqB;;;;;;;;;;;iBAYrB,YAAY,UAAU,QAAQ,OACrD,QAAQ,kBACR,eACE,aAAa;;;;;;;;;;;;;;;;;iBCZQ,WAAW,+BAA+B,aAAa;;;;;;;;;;;;;;;;;iBCAvD,cAAc,+BAA+B,aAAa"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { t as Cleanup } from "./Cleanup-D0wvGW5d.cjs";
|
|
2
|
+
//#region src/types/ClassValue.d.ts
|
|
3
|
+
type ClassValue = string | Record<string, boolean | null | undefined> | Array<ClassValue> | null | undefined;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/render/buildClasses.d.ts
|
|
6
|
+
declare function buildClasses(value: ClassValue, styleHash?: string): string;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/types/StyleValue.d.ts
|
|
9
|
+
type StyleValue = string | Record<string, string | null | undefined> | Array<StyleValue> | null | undefined;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/render/buildStyles.d.ts
|
|
12
|
+
declare function buildStyles(value: StyleValue): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/types/StreamSource.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* A subscription to an external source of events — server-sent events,
|
|
17
|
+
* WebSockets, DOM events, intervals, or anything else that pushes values
|
|
18
|
+
* over time.
|
|
19
|
+
*
|
|
20
|
+
* The function is called with a `push` callback when the stream is
|
|
21
|
+
* subscribed to (at mount time, and again whenever reactive state read
|
|
22
|
+
* inside it changes). It wires the external source up to `push` and returns
|
|
23
|
+
* a cleanup function that unsubscribes.
|
|
24
|
+
*
|
|
25
|
+
* Sources are never invoked during a server render, so browser-only APIs
|
|
26
|
+
* (`EventSource`, `WebSocket`, DOM elements) are safe to reference inside
|
|
27
|
+
* them.
|
|
28
|
+
*/
|
|
29
|
+
type StreamSource<T> = (push: (value: T) => void) => Cleanup | void;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/stream/fromElement.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* The element to listen on, or a getter returning it. Use a getter for
|
|
34
|
+
* `&ref`-bound variables — they are only assigned once the element is
|
|
35
|
+
* created, and subscriptions start at mount time:
|
|
36
|
+
*
|
|
37
|
+
* ```torp
|
|
38
|
+
* let saveButton: HTMLButtonElement;
|
|
39
|
+
*
|
|
40
|
+
* $stream(fromElement(() => saveButton, "click"), () => save());
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
type EventTargetInput = HTMLElement | (() => HTMLElement | null | undefined);
|
|
44
|
+
/**
|
|
45
|
+
* Creates a StreamSource that pushes DOM events of the given type from an
|
|
46
|
+
* element.
|
|
47
|
+
*
|
|
48
|
+
* ```torp
|
|
49
|
+
* $stream(fromElement(() => saveButton, "click"), (e) => {
|
|
50
|
+
* $state.clicks.push(e);
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
declare function fromElement<E extends Event = Event>(target: EventTargetInput, type: string): StreamSource<E>;
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/stream/fromServer.d.ts
|
|
57
|
+
/**
|
|
58
|
+
* Creates a StreamSource that receives `message` events from a server-sent
|
|
59
|
+
* events endpoint. The URL may be a getter, so reactive state can be read
|
|
60
|
+
* inside it — when it changes, the connection is closed and re-opened:
|
|
61
|
+
*
|
|
62
|
+
* ```torp
|
|
63
|
+
* $stream(fromServer(`/sse/${$props.id}`), (e) => {
|
|
64
|
+
* $state.messages.push(e.data);
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* Reconnection is handled by `EventSource` itself; errors are not pushed —
|
|
69
|
+
* a source that can fail should surface errors as values.
|
|
70
|
+
*/
|
|
71
|
+
declare function fromServer(url: string | (() => string)): StreamSource<MessageEvent>;
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/stream/fromWebSocket.d.ts
|
|
74
|
+
/**
|
|
75
|
+
* Creates a StreamSource that receives `message` events from a WebSocket.
|
|
76
|
+
* The URL may be a getter, so reactive state can be read inside it — when
|
|
77
|
+
* it changes, the socket is closed and re-opened:
|
|
78
|
+
*
|
|
79
|
+
* ```torp
|
|
80
|
+
* $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {
|
|
81
|
+
* $state.inbox.push(e.data);
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* Errors are not pushed — a source that can fail should surface errors as
|
|
86
|
+
* values and own its own reconnection.
|
|
87
|
+
*/
|
|
88
|
+
declare function fromWebSocket(url: string | (() => string)): StreamSource<MessageEvent>;
|
|
89
|
+
//#endregion
|
|
90
|
+
export { buildStyles as a, ClassValue as c, StreamSource as i, fromServer as n, StyleValue as o, fromElement as r, buildClasses as s, fromWebSocket as t };
|
|
91
|
+
//# sourceMappingURL=fromWebSocket-DeB35Q4w.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fromWebSocket-DeB35Q4w.d.cts","names":[],"sources":["../src/types/ClassValue.ts","../src/render/buildClasses.ts","../src/types/StyleValue.ts","../src/render/buildStyles.ts","../src/types/StreamSource.ts","../src/stream/fromElement.ts","../src/stream/fromServer.ts","../src/stream/fromWebSocket.ts"],"mappings":";;KAAK,sBAEF,6CACA,MAAM;;;iBCAe,aAAa,OAAO,YAAY;;;KCHnD,sBAEF,4CACA,MAAM;;;iBCCe,YAAY,OAAO;;;;;;;;;;;;;;;;;KCYtC,aAAa,MAAM,OAAO,OAAO,eAAe;;;;;;;;;;;;;;KCHhD,mBAAmB,qBAAqB;;;;;;;;;;;iBAYrB,YAAY,UAAU,QAAQ,OACrD,QAAQ,kBACR,eACE,aAAa;;;;;;;;;;;;;;;;;iBCZQ,WAAW,+BAA+B,aAAa;;;;;;;;;;;;;;;;;iBCAvD,cAAc,+BAA+B,aAAa"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
//#region src/watch/symbols.ts
|
|
2
|
+
const proxyDataSymbol = Symbol.for("torp.ProxyData");
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region src/watch/$unwrap.ts
|
|
5
|
+
/**
|
|
6
|
+
* Returns the target object of a proxy
|
|
7
|
+
*
|
|
8
|
+
* @param object The proxy object
|
|
9
|
+
*/
|
|
10
|
+
function $unwrap(object) {
|
|
11
|
+
return object !== void 0 && object !== null && object[proxyDataSymbol] !== void 0 ? object[proxyDataSymbol].target ?? object : object;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/render/buildClasses.ts
|
|
15
|
+
function buildClasses(value, styleHash) {
|
|
16
|
+
if (typeof value === "string") {
|
|
17
|
+
if (styleHash !== void 0) value += " " + styleHash;
|
|
18
|
+
return value;
|
|
19
|
+
} else {
|
|
20
|
+
let classes = [];
|
|
21
|
+
gatherClasses("", value, classes);
|
|
22
|
+
if (styleHash !== void 0) classes.push(styleHash);
|
|
23
|
+
return classes.join(" ");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function gatherClasses(name, value, classes) {
|
|
27
|
+
if (value) {
|
|
28
|
+
value = $unwrap(value);
|
|
29
|
+
if (Array.isArray(value)) for (let v of value) gatherClasses(v, v, classes);
|
|
30
|
+
else if (typeof value === "object") for (const n in value) gatherClasses(n, value[n], classes);
|
|
31
|
+
else classes.push(name);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/render/buildStyles.ts
|
|
36
|
+
const CAMEL_TO_DASH = /[A-Z]+(?![a-z])|[A-Z]/g;
|
|
37
|
+
function buildStyles(value) {
|
|
38
|
+
if (typeof value === "string") return value;
|
|
39
|
+
else {
|
|
40
|
+
let styles = [];
|
|
41
|
+
gatherStyles(value, styles);
|
|
42
|
+
return styles.join("; ");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function gatherStyles(value, styles) {
|
|
46
|
+
if (value) if (Array.isArray(value)) for (let v of value) gatherStyles(v, styles);
|
|
47
|
+
else if (typeof value === "object") for (let [n, v] of Object.entries(value)) {
|
|
48
|
+
if (v === null || v === void 0) continue;
|
|
49
|
+
const key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? "-" : "") + char.toLowerCase());
|
|
50
|
+
styles.push(`${key}: ${v}`);
|
|
51
|
+
}
|
|
52
|
+
else styles.push(String(value));
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/render/formatText.ts
|
|
56
|
+
function formatText(value) {
|
|
57
|
+
if (value === void 0 || value === null) return "";
|
|
58
|
+
if (typeof value === "string") return value;
|
|
59
|
+
return String($unwrap(value));
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/stream/fromElement.ts
|
|
63
|
+
/**
|
|
64
|
+
* Creates a StreamSource that pushes DOM events of the given type from an
|
|
65
|
+
* element.
|
|
66
|
+
*
|
|
67
|
+
* ```torp
|
|
68
|
+
* $stream(fromElement(() => saveButton, "click"), (e) => {
|
|
69
|
+
* $state.clicks.push(e);
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
function fromElement(target, type) {
|
|
74
|
+
return (push) => {
|
|
75
|
+
const el = typeof target === "function" ? target() : target;
|
|
76
|
+
if (!el) throw new Error("fromElement: element not found. When passing a &ref variable, wrap it in a getter: fromElement(() => buttonEl, \"click\")");
|
|
77
|
+
const listener = push;
|
|
78
|
+
el.addEventListener(type, listener);
|
|
79
|
+
return () => {
|
|
80
|
+
el.removeEventListener(type, listener);
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/stream/fromServer.ts
|
|
86
|
+
/**
|
|
87
|
+
* Creates a StreamSource that receives `message` events from a server-sent
|
|
88
|
+
* events endpoint. The URL may be a getter, so reactive state can be read
|
|
89
|
+
* inside it — when it changes, the connection is closed and re-opened:
|
|
90
|
+
*
|
|
91
|
+
* ```torp
|
|
92
|
+
* $stream(fromServer(`/sse/${$props.id}`), (e) => {
|
|
93
|
+
* $state.messages.push(e.data);
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* Reconnection is handled by `EventSource` itself; errors are not pushed —
|
|
98
|
+
* a source that can fail should surface errors as values.
|
|
99
|
+
*/
|
|
100
|
+
function fromServer(url) {
|
|
101
|
+
return (push) => {
|
|
102
|
+
const eventSource = new EventSource(typeof url === "function" ? url() : url);
|
|
103
|
+
eventSource.onmessage = push;
|
|
104
|
+
return () => {
|
|
105
|
+
eventSource.close();
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/stream/fromWebSocket.ts
|
|
111
|
+
/**
|
|
112
|
+
* Creates a StreamSource that receives `message` events from a WebSocket.
|
|
113
|
+
* The URL may be a getter, so reactive state can be read inside it — when
|
|
114
|
+
* it changes, the socket is closed and re-opened:
|
|
115
|
+
*
|
|
116
|
+
* ```torp
|
|
117
|
+
* $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {
|
|
118
|
+
* $state.inbox.push(e.data);
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* Errors are not pushed — a source that can fail should surface errors as
|
|
123
|
+
* values and own its own reconnection.
|
|
124
|
+
*/
|
|
125
|
+
function fromWebSocket(url) {
|
|
126
|
+
return (push) => {
|
|
127
|
+
const socket = new WebSocket(typeof url === "function" ? url() : url);
|
|
128
|
+
socket.onmessage = push;
|
|
129
|
+
return () => {
|
|
130
|
+
socket.close();
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { buildStyles as a, proxyDataSymbol as c, formatText as i, fromServer as n, buildClasses as o, fromElement as r, $unwrap as s, fromWebSocket as t };
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=fromWebSocket-Dxc_uwm1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fromWebSocket-Dxc_uwm1.mjs","names":[],"sources":["../src/watch/symbols.ts","../src/watch/$unwrap.ts","../src/render/buildClasses.ts","../src/render/buildStyles.ts","../src/render/formatText.ts","../src/stream/fromElement.ts","../src/stream/fromServer.ts","../src/stream/fromWebSocket.ts"],"sourcesContent":["const proxyDataSymbol: unique symbol = Symbol.for(\"torp.ProxyData\");\n\nexport { proxyDataSymbol };\n","import { proxyDataSymbol } from \"./symbols\";\n\n/**\n * Returns the target object of a proxy\n *\n * @param object The proxy object\n */\nexport default function $unwrap<T extends Record<PropertyKey, any>>(object: T): T {\n\treturn object !== undefined && object !== null && object[proxyDataSymbol] !== undefined\n\t\t? (object[proxyDataSymbol].target ?? object)\n\t\t: object;\n}\n","import ClassValue from \"../types/ClassValue\";\nimport $unwrap from \"../watch/$unwrap\";\n\nexport default function buildClasses(value: ClassValue, styleHash?: string): string {\n\tif (typeof value === \"string\") {\n\t\tif (styleHash !== undefined) {\n\t\t\tvalue += \" \" + styleHash;\n\t\t}\n\t\treturn value;\n\t} else {\n\t\tlet classes: string[] = [];\n\t\tgatherClasses(\"\", value, classes);\n\t\tif (styleHash !== undefined) {\n\t\t\tclasses.push(styleHash);\n\t\t}\n\t\treturn classes.join(\" \");\n\t}\n}\n\nfunction gatherClasses(name: string, value: unknown, classes: string[]) {\n\tif (value) {\n\t\t// Unwrap watched values before iterating: component props are\n\t\t// deep-wrapped, and iterating a watched array disables the active\n\t\t// effect (see the array iterator in proxyGet), which would break\n\t\t// tracking of reads later in the same effect. Per-element tracking is\n\t\t// unnecessary here anyway -- the caller has already subscribed to the\n\t\t// property read that produced the value\n\t\tvalue = $unwrap(value as Record<PropertyKey, any>);\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (let v of value) {\n\t\t\t\tgatherClasses(v as string, v, classes);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\t// Use `for-in` instead of `Object.entries(value)`. The entries\n\t\t\t// call allocates a new array (plus a [k, v] pair per entry) on\n\t\t\t// every invocation; `for-in` allocates nothing. Object literals\n\t\t\t// (the dominant case — e.g. `{ danger: bool }` in the row\n\t\t\t// template) have no inherited enumerable properties, so the two\n\t\t\t// are equivalent for our usage. This is on the per-effect re-run\n\t\t\t// hot path: a `select` op re-runs every row effect, each calling\n\t\t\t// `buildClasses({ danger: ... })`.\n\t\t\tfor (const n in value) {\n\t\t\t\tgatherClasses(n, (value as Record<string, unknown>)[n], classes);\n\t\t\t}\n\t\t} else {\n\t\t\tclasses.push(name);\n\t\t}\n\t}\n}\n","import type StyleValue from \"../types/StyleValue\";\n\nconst CAMEL_TO_DASH = /[A-Z]+(?![a-z])|[A-Z]/g;\n\nexport default function buildStyles(value: StyleValue): string {\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t} else {\n\t\tlet styles: string[] = [];\n\t\tgatherStyles(value, styles);\n\t\treturn styles.join(\"; \");\n\t}\n}\n\nfunction gatherStyles(value: unknown, styles: string[]) {\n\tif (value) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (let v of value) {\n\t\t\t\tgatherStyles(v, styles);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\tfor (let [n, v] of Object.entries(value)) {\n\t\t\t\tif (v === null || v === undefined) continue;\n\t\t\t\tconst key = n.replace(CAMEL_TO_DASH, (char, i) => (i > 0 ? \"-\" : \"\") + char.toLowerCase());\n\t\t\t\tstyles.push(`${key}: ${v}`);\n\t\t\t}\n\t\t} else {\n\t\t\t// oxlint-disable-next-line typescript/no-base-to-string\n\t\t\tstyles.push(String(value));\n\t\t}\n\t}\n}\n","import $unwrap from \"../watch/$unwrap\";\n\nexport default function formatText(value: any): string {\n\t// We could have anything in value, so we need to\n\t// - use String(...) because Symbols can't be implicitly converted\n\t// - use $unwrap because Proxies can't be converted to a string\n\tif (value === undefined || value === null) {\n\t\treturn \"\";\n\t}\n\t// Fast path: strings already satisfy both concerns above. Skipping the\n\t// `String($unwrap(value))` pair saves two function calls per text\n\t// interpolation on the dominant `typeof value === \"string\"` branch —\n\t// e.g. row labels in js-framework-bench hit this on every effect run.\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t}\n\treturn String($unwrap(value));\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * The element to listen on, or a getter returning it. Use a getter for\n * `&ref`-bound variables — they are only assigned once the element is\n * created, and subscriptions start at mount time:\n *\n * ```torp\n * let saveButton: HTMLButtonElement;\n *\n * $stream(fromElement(() => saveButton, \"click\"), () => save());\n * ```\n */\ntype EventTargetInput = HTMLElement | (() => HTMLElement | null | undefined);\n\n/**\n * Creates a StreamSource that pushes DOM events of the given type from an\n * element.\n *\n * ```torp\n * $stream(fromElement(() => saveButton, \"click\"), (e) => {\n * \t$state.clicks.push(e);\n * });\n * ```\n */\nexport default function fromElement<E extends Event = Event>(\n\ttarget: EventTargetInput,\n\ttype: string,\n): StreamSource<E> {\n\treturn (push) => {\n\t\tconst el = typeof target === \"function\" ? target() : target;\n\t\tif (!el) {\n\t\t\tthrow new Error(\n\t\t\t\t'fromElement: element not found. When passing a &ref variable, wrap it in a getter: fromElement(() => buttonEl, \"click\")',\n\t\t\t);\n\t\t}\n\t\tconst listener = push as EventListener;\n\t\tel.addEventListener(type, listener);\n\t\treturn () => {\n\t\t\tel.removeEventListener(type, listener);\n\t\t};\n\t};\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * Creates a StreamSource that receives `message` events from a server-sent\n * events endpoint. The URL may be a getter, so reactive state can be read\n * inside it — when it changes, the connection is closed and re-opened:\n *\n * ```torp\n * $stream(fromServer(`/sse/${$props.id}`), (e) => {\n * \t$state.messages.push(e.data);\n * });\n * ```\n *\n * Reconnection is handled by `EventSource` itself; errors are not pushed —\n * a source that can fail should surface errors as values.\n */\nexport default function fromServer(url: string | (() => string)): StreamSource<MessageEvent> {\n\treturn (push) => {\n\t\tconst eventSource = new EventSource(typeof url === \"function\" ? url() : url);\n\t\teventSource.onmessage = push;\n\t\treturn () => {\n\t\t\teventSource.close();\n\t\t};\n\t};\n}\n","import type StreamSource from \"../types/StreamSource\";\n\n/**\n * Creates a StreamSource that receives `message` events from a WebSocket.\n * The URL may be a getter, so reactive state can be read inside it — when\n * it changes, the socket is closed and re-opened:\n *\n * ```torp\n * $stream(fromWebSocket(`/ws/${$props.id}`), (e) => {\n * \t$state.inbox.push(e.data);\n * });\n * ```\n *\n * Errors are not pushed — a source that can fail should surface errors as\n * values and own its own reconnection.\n */\nexport default function fromWebSocket(url: string | (() => string)): StreamSource<MessageEvent> {\n\treturn (push) => {\n\t\tconst socket = new WebSocket(typeof url === \"function\" ? url() : url);\n\t\tsocket.onmessage = push;\n\t\treturn () => {\n\t\t\tsocket.close();\n\t\t};\n\t};\n}\n"],"mappings":";AAAA,MAAM,kBAAiC,OAAO,IAAI,gBAAgB;;;;;;;;ACOlE,SAAwB,QAA4C,QAAc;CACjF,OAAO,WAAW,KAAA,KAAa,WAAW,QAAQ,OAAO,qBAAqB,KAAA,IAC1E,OAAO,gBAAgB,CAAC,UAAU,SACnC;AACJ;;;ACRA,SAAwB,aAAa,OAAmB,WAA4B;CACnF,IAAI,OAAO,UAAU,UAAU;EAC9B,IAAI,cAAc,KAAA,GACjB,SAAS,MAAM;EAEhB,OAAO;CACR,OAAO;EACN,IAAI,UAAoB,CAAC;EACzB,cAAc,IAAI,OAAO,OAAO;EAChC,IAAI,cAAc,KAAA,GACjB,QAAQ,KAAK,SAAS;EAEvB,OAAO,QAAQ,KAAK,GAAG;CACxB;AACD;AAEA,SAAS,cAAc,MAAc,OAAgB,SAAmB;CACvE,IAAI,OAAO;EAOV,QAAQ,QAAQ,KAAiC;EACjD,IAAI,MAAM,QAAQ,KAAK,GACtB,KAAK,IAAI,KAAK,OACb,cAAc,GAAa,GAAG,OAAO;OAEhC,IAAI,OAAO,UAAU,UAS3B,KAAK,MAAM,KAAK,OACf,cAAc,GAAI,MAAkC,IAAI,OAAO;OAGhE,QAAQ,KAAK,IAAI;CAEnB;AACD;;;AC9CA,MAAM,gBAAgB;AAEtB,SAAwB,YAAY,OAA2B;CAC9D,IAAI,OAAO,UAAU,UACpB,OAAO;MACD;EACN,IAAI,SAAmB,CAAC;EACxB,aAAa,OAAO,MAAM;EAC1B,OAAO,OAAO,KAAK,IAAI;CACxB;AACD;AAEA,SAAS,aAAa,OAAgB,QAAkB;CACvD,IAAI,OACH,IAAI,MAAM,QAAQ,KAAK,GACtB,KAAK,IAAI,KAAK,OACb,aAAa,GAAG,MAAM;MAEjB,IAAI,OAAO,UAAU,UAC3B,KAAK,IAAI,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,GAAG;EACzC,IAAI,MAAM,QAAQ,MAAM,KAAA,GAAW;EACnC,MAAM,MAAM,EAAE,QAAQ,gBAAgB,MAAM,OAAO,IAAI,IAAI,MAAM,MAAM,KAAK,YAAY,CAAC;EACzF,OAAO,KAAK,GAAG,IAAI,IAAI,GAAG;CAC3B;MAGA,OAAO,KAAK,OAAO,KAAK,CAAC;AAG5B;;;AC7BA,SAAwB,WAAW,OAAoB;CAItD,IAAI,UAAU,KAAA,KAAa,UAAU,MACpC,OAAO;CAMR,IAAI,OAAO,UAAU,UACpB,OAAO;CAER,OAAO,OAAO,QAAQ,KAAK,CAAC;AAC7B;;;;;;;;;;;;;ACQA,SAAwB,YACvB,QACA,MACkB;CAClB,QAAQ,SAAS;EAChB,MAAM,KAAK,OAAO,WAAW,aAAa,OAAO,IAAI;EACrD,IAAI,CAAC,IACJ,MAAM,IAAI,MACT,2HACD;EAED,MAAM,WAAW;EACjB,GAAG,iBAAiB,MAAM,QAAQ;EAClC,aAAa;GACZ,GAAG,oBAAoB,MAAM,QAAQ;EACtC;CACD;AACD;;;;;;;;;;;;;;;;;AC1BA,SAAwB,WAAW,KAA0D;CAC5F,QAAQ,SAAS;EAChB,MAAM,cAAc,IAAI,YAAY,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAG;EAC3E,YAAY,YAAY;EACxB,aAAa;GACZ,YAAY,MAAM;EACnB;CACD;AACD;;;;;;;;;;;;;;;;;ACRA,SAAwB,cAAc,KAA0D;CAC/F,QAAQ,SAAS;EAChB,MAAM,SAAS,IAAI,UAAU,OAAO,QAAQ,aAAa,IAAI,IAAI,GAAG;EACpE,OAAO,YAAY;EACnB,aAAa;GACZ,OAAO,MAAM;EACd;CACD;AACD"}
|