sigmx 0.1.0 → 0.2.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 +54 -43
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +2 -2
- package/dist/kernel/compile.d.ts +8 -9
- package/dist/kernel/compile.js +102 -67
- package/dist/kernel/compile.js.map +2 -2
- package/dist/kernel/contracts.d.ts +12 -13
- package/dist/kernel/index.d.ts +11 -12
- package/dist/kernel/index.js +14 -12
- package/dist/kernel/index.js.map +3 -3
- package/dist/kernel/precompile.d.ts +8 -12
- package/dist/kernel/precompile.js +33 -76
- package/dist/kernel/precompile.js.map +2 -2
- package/dist/kernel/precompiled.d.ts +7 -4
- package/dist/kernel/precompiled.js +5 -5
- package/dist/kernel/precompiled.js.map +2 -2
- package/dist/kernel/reactive.d.ts +13 -11
- package/dist/kernel/reactive.js +96 -71
- package/dist/kernel/reactive.js.map +3 -3
- package/dist/kernel/runtime.js +85 -63
- package/dist/kernel/runtime.js.map +3 -3
- package/dist/kernel/scan.d.ts +2 -11
- package/dist/kernel/scan.js +26 -9
- package/dist/kernel/scan.js.map +2 -2
- package/dist/kernel/state.d.ts +5 -8
- package/dist/kernel/state.js +114 -76
- package/dist/kernel/state.js.map +2 -2
- package/dist/kernel/strict-csp.d.ts +0 -5
- package/dist/kernel/strict-csp.js +2 -2
- package/dist/kernel/strict-csp.js.map +2 -2
- package/dist/lib/casing.d.ts +4 -1
- package/dist/lib/casing.js +8 -1
- package/dist/lib/casing.js.map +2 -2
- package/dist/lib/objects.d.ts +5 -4
- package/dist/lib/objects.js +13 -5
- package/dist/lib/objects.js.map +2 -2
- package/dist/lib/schedule.d.ts +3 -5
- package/dist/lib/schedule.js +12 -10
- package/dist/lib/schedule.js.map +2 -2
- package/dist/lib/sse.d.ts +10 -1
- package/dist/lib/sse.js +32 -28
- package/dist/lib/sse.js.map +2 -2
- package/dist/plugins/def.d.ts +5 -0
- package/dist/plugins/def.js +22 -0
- package/dist/plugins/def.js.map +7 -0
- package/dist/plugins/directives/attribute-sync.js +8 -12
- package/dist/plugins/directives/attribute-sync.js.map +2 -2
- package/dist/plugins/directives/boost.d.ts +1 -1
- package/dist/plugins/directives/boost.js +34 -30
- package/dist/plugins/directives/boost.js.map +2 -2
- package/dist/plugins/directives/busy-flag.js +13 -16
- package/dist/plugins/directives/busy-flag.js.map +2 -2
- package/dist/plugins/directives/class-toggle.js +17 -16
- package/dist/plugins/directives/class-toggle.js.map +2 -2
- package/dist/plugins/directives/cloak.js +2 -7
- package/dist/plugins/directives/cloak.js.map +2 -2
- package/dist/plugins/directives/collapse.js +36 -37
- package/dist/plugins/directives/collapse.js.map +2 -2
- package/dist/plugins/directives/declare.js +5 -8
- package/dist/plugins/directives/declare.js.map +2 -2
- package/dist/plugins/directives/derive.js +9 -15
- package/dist/plugins/directives/derive.js.map +2 -2
- package/dist/plugins/directives/element-ref.js +8 -8
- package/dist/plugins/directives/element-ref.js.map +2 -2
- package/dist/plugins/directives/event-listener.js +18 -23
- package/dist/plugins/directives/event-listener.js.map +2 -2
- package/dist/plugins/directives/frame-loop.js +9 -14
- package/dist/plugins/directives/frame-loop.js.map +2 -2
- package/dist/plugins/directives/html.js +6 -7
- package/dist/plugins/directives/html.js.map +2 -2
- package/dist/plugins/directives/inline-style.js +17 -20
- package/dist/plugins/directives/inline-style.js.map +2 -2
- package/dist/plugins/directives/mask.js +19 -23
- package/dist/plugins/directives/mask.js.map +2 -2
- package/dist/plugins/directives/media-query.d.ts +4 -1
- package/dist/plugins/directives/media-query.js +13 -12
- package/dist/plugins/directives/media-query.js.map +2 -2
- package/dist/plugins/directives/on-mount.js +4 -9
- package/dist/plugins/directives/on-mount.js.map +2 -2
- package/dist/plugins/directives/patch-listener.js +24 -19
- package/dist/plugins/directives/patch-listener.js.map +2 -2
- package/dist/plugins/directives/remove-me.js +7 -8
- package/dist/plugins/directives/remove-me.js.map +2 -2
- package/dist/plugins/directives/scroll-to.d.ts +4 -1
- package/dist/plugins/directives/scroll-to.js +8 -14
- package/dist/plugins/directives/scroll-to.js.map +2 -2
- package/dist/plugins/directives/size-watch.js +7 -12
- package/dist/plugins/directives/size-watch.js.map +2 -2
- package/dist/plugins/directives/state-dump.js +6 -10
- package/dist/plugins/directives/state-dump.js.map +2 -2
- package/dist/plugins/directives/storage-sync.js +13 -9
- package/dist/plugins/directives/storage-sync.js.map +2 -2
- package/dist/plugins/directives/teleport.js +8 -14
- package/dist/plugins/directives/teleport.js.map +2 -2
- package/dist/plugins/directives/text-content.js +6 -7
- package/dist/plugins/directives/text-content.js.map +2 -2
- package/dist/plugins/directives/timer.js +7 -13
- package/dist/plugins/directives/timer.js.map +2 -2
- package/dist/plugins/directives/transition.d.ts +1 -2
- package/dist/plugins/directives/transition.js +32 -34
- package/dist/plugins/directives/transition.js.map +2 -2
- package/dist/plugins/directives/tween.d.ts +2 -2
- package/dist/plugins/directives/tween.js +34 -50
- package/dist/plugins/directives/tween.js.map +2 -2
- package/dist/plugins/directives/two-way-bind.d.ts +1 -1
- package/dist/plugins/directives/two-way-bind.js +70 -67
- package/dist/plugins/directives/two-way-bind.js.map +2 -2
- package/dist/plugins/directives/url-params.js +36 -59
- package/dist/plugins/directives/url-params.js.map +3 -3
- package/dist/plugins/directives/url-replace.js +6 -7
- package/dist/plugins/directives/url-replace.js.map +2 -2
- package/dist/plugins/directives/validity.js +6 -9
- package/dist/plugins/directives/validity.js.map +2 -2
- package/dist/plugins/directives/viewport.js +18 -23
- package/dist/plugins/directives/viewport.js.map +2 -2
- package/dist/plugins/directives/visibility.js +9 -14
- package/dist/plugins/directives/visibility.js.map +2 -2
- package/dist/plugins/directives/watch.d.ts +0 -1
- package/dist/plugins/directives/watch.js +2 -8
- package/dist/plugins/directives/watch.js.map +2 -2
- package/dist/plugins/functions/bulk-set.js +10 -7
- package/dist/plugins/functions/bulk-set.js.map +2 -2
- package/dist/plugins/functions/bulk-toggle.js +10 -7
- package/dist/plugins/functions/bulk-toggle.js.map +2 -2
- package/dist/plugins/functions/confirm.js +2 -2
- package/dist/plugins/functions/confirm.js.map +2 -2
- package/dist/plugins/functions/copy-text.js +5 -5
- package/dist/plugins/functions/copy-text.js.map +2 -2
- package/dist/plugins/functions/dispatch.js +5 -5
- package/dist/plugins/functions/dispatch.js.map +2 -2
- package/dist/plugins/functions/locale-format.d.ts +4 -1
- package/dist/plugins/functions/locale-format.js +9 -16
- package/dist/plugins/functions/locale-format.js.map +2 -2
- package/dist/plugins/functions/range-map.js +6 -6
- package/dist/plugins/functions/range-map.js.map +2 -2
- package/dist/plugins/functions/request.d.ts +7 -3
- package/dist/plugins/functions/request.js +85 -80
- package/dist/plugins/functions/request.js.map +2 -2
- package/dist/plugins/functions/untracked-read.js +3 -2
- package/dist/plugins/functions/untracked-read.js.map +2 -2
- package/dist/plugins/functions/websocket.d.ts +3 -3
- package/dist/plugins/functions/websocket.js +18 -25
- package/dist/plugins/functions/websocket.js.map +2 -2
- package/dist/plugins/index.d.ts +34 -36
- package/dist/plugins/index.js +31 -35
- package/dist/plugins/index.js.map +2 -2
- package/dist/plugins/server-events/apply-elements.d.ts +1 -1
- package/dist/plugins/server-events/apply-elements.js +41 -40
- package/dist/plugins/server-events/apply-elements.js.map +2 -2
- package/dist/plugins/server-events/apply-state.js +9 -12
- package/dist/plugins/server-events/apply-state.js.map +2 -2
- package/dist/plugins/server-events/morph.d.ts +0 -2
- package/dist/plugins/server-events/morph.js +58 -55
- package/dist/plugins/server-events/morph.js.map +3 -3
- package/dist/presets/all.d.ts +0 -1
- package/dist/presets/all.js +22 -26
- package/dist/presets/all.js.map +2 -2
- package/dist/presets/essentials.d.ts +0 -1
- package/dist/presets/essentials.js +27 -9
- package/dist/presets/essentials.js.map +2 -2
- package/dist/presets/minimal.d.ts +0 -1
- package/dist/presets/minimal.js +2 -2
- package/dist/presets/minimal.js.map +2 -2
- package/dist/server.d.ts +108 -0
- package/dist/server.js +218 -0
- package/dist/server.js.map +7 -0
- package/dist/sigmx.standalone.js +1 -1
- package/dist/standalone.js.map +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +48 -15
- package/dist/vite.js.map +2 -2
- package/package.json +21 -2
- package/dist/auto.d.ts +0 -1
- package/dist/auto.js +0 -7
- package/dist/auto.js.map +0 -7
- package/dist/core/csp.d.ts +0 -7
- package/dist/core/csp.js +0 -20
- package/dist/core/csp.js.map +0 -7
- package/dist/core/engine.d.ts +0 -10
- package/dist/core/engine.js +0 -200
- package/dist/core/engine.js.map +0 -7
- package/dist/core/expr.d.ts +0 -12
- package/dist/core/expr.js +0 -94
- package/dist/core/expr.js.map +0 -7
- package/dist/core/index.d.ts +0 -16
- package/dist/core/index.js +0 -46
- package/dist/core/index.js.map +0 -7
- package/dist/core/signals.d.ts +0 -42
- package/dist/core/signals.js +0 -195
- package/dist/core/signals.js.map +0 -7
- package/dist/core/store.d.ts +0 -32
- package/dist/core/store.js +0 -185
- package/dist/core/store.js.map +0 -7
- package/dist/core/types.d.ts +0 -101
- package/dist/core/types.js +0 -1
- package/dist/core/types.js.map +0 -7
- package/dist/plugins/actions/clipboard.d.ts +0 -2
- package/dist/plugins/actions/clipboard.js +0 -11
- package/dist/plugins/actions/clipboard.js.map +0 -7
- package/dist/plugins/actions/fit.d.ts +0 -2
- package/dist/plugins/actions/fit.js +0 -14
- package/dist/plugins/actions/fit.js.map +0 -7
- package/dist/plugins/actions/intl.d.ts +0 -2
- package/dist/plugins/actions/intl.js +0 -21
- package/dist/plugins/actions/intl.js.map +0 -7
- package/dist/plugins/actions/peek.d.ts +0 -2
- package/dist/plugins/actions/peek.js +0 -6
- package/dist/plugins/actions/peek.js.map +0 -7
- package/dist/plugins/actions/setAll.d.ts +0 -2
- package/dist/plugins/actions/setAll.js +0 -11
- package/dist/plugins/actions/setAll.js.map +0 -7
- package/dist/plugins/actions/toggleAll.d.ts +0 -2
- package/dist/plugins/actions/toggleAll.js +0 -11
- package/dist/plugins/actions/toggleAll.js.map +0 -7
- package/dist/plugins/attributes/attr.d.ts +0 -2
- package/dist/plugins/attributes/attr.js +0 -20
- package/dist/plugins/attributes/attr.js.map +0 -7
- package/dist/plugins/attributes/bind.d.ts +0 -6
- package/dist/plugins/attributes/bind.js +0 -81
- package/dist/plugins/attributes/bind.js.map +0 -7
- package/dist/plugins/attributes/class.d.ts +0 -2
- package/dist/plugins/attributes/class.js +0 -22
- package/dist/plugins/attributes/class.js.map +0 -7
- package/dist/plugins/attributes/computed.d.ts +0 -2
- package/dist/plugins/attributes/computed.js +0 -20
- package/dist/plugins/attributes/computed.js.map +0 -7
- package/dist/plugins/attributes/customValidity.d.ts +0 -2
- package/dist/plugins/attributes/customValidity.js +0 -14
- package/dist/plugins/attributes/customValidity.js.map +0 -7
- package/dist/plugins/attributes/effect.d.ts +0 -2
- package/dist/plugins/attributes/effect.js +0 -12
- package/dist/plugins/attributes/effect.js.map +0 -7
- package/dist/plugins/attributes/indicator.d.ts +0 -2
- package/dist/plugins/attributes/indicator.js +0 -20
- package/dist/plugins/attributes/indicator.js.map +0 -7
- package/dist/plugins/attributes/init.d.ts +0 -2
- package/dist/plugins/attributes/init.js +0 -14
- package/dist/plugins/attributes/init.js.map +0 -7
- package/dist/plugins/attributes/jsonSignals.d.ts +0 -2
- package/dist/plugins/attributes/jsonSignals.js +0 -15
- package/dist/plugins/attributes/jsonSignals.js.map +0 -7
- package/dist/plugins/attributes/matchMedia.d.ts +0 -2
- package/dist/plugins/attributes/matchMedia.js +0 -19
- package/dist/plugins/attributes/matchMedia.js.map +0 -7
- package/dist/plugins/attributes/on.d.ts +0 -5
- package/dist/plugins/attributes/on.js +0 -28
- package/dist/plugins/attributes/on.js.map +0 -7
- package/dist/plugins/attributes/onIntersect.d.ts +0 -2
- package/dist/plugins/attributes/onIntersect.js +0 -28
- package/dist/plugins/attributes/onIntersect.js.map +0 -7
- package/dist/plugins/attributes/onInterval.d.ts +0 -2
- package/dist/plugins/attributes/onInterval.js +0 -18
- package/dist/plugins/attributes/onInterval.js.map +0 -7
- package/dist/plugins/attributes/onRaf.d.ts +0 -1
- package/dist/plugins/attributes/onRaf.js +0 -19
- package/dist/plugins/attributes/onRaf.js.map +0 -7
- package/dist/plugins/attributes/onResize.d.ts +0 -1
- package/dist/plugins/attributes/onResize.js +0 -17
- package/dist/plugins/attributes/onResize.js.map +0 -7
- package/dist/plugins/attributes/onSignalPatch.d.ts +0 -5
- package/dist/plugins/attributes/onSignalPatch.js +0 -35
- package/dist/plugins/attributes/onSignalPatch.js.map +0 -7
- package/dist/plugins/attributes/persist.d.ts +0 -6
- package/dist/plugins/attributes/persist.js +0 -16
- package/dist/plugins/attributes/persist.js.map +0 -7
- package/dist/plugins/attributes/queryString.d.ts +0 -5
- package/dist/plugins/attributes/queryString.js +0 -54
- package/dist/plugins/attributes/queryString.js.map +0 -7
- package/dist/plugins/attributes/ref.d.ts +0 -2
- package/dist/plugins/attributes/ref.js +0 -13
- package/dist/plugins/attributes/ref.js.map +0 -7
- package/dist/plugins/attributes/replaceUrl.d.ts +0 -1
- package/dist/plugins/attributes/replaceUrl.js +0 -11
- package/dist/plugins/attributes/replaceUrl.js.map +0 -7
- package/dist/plugins/attributes/scrollIntoView.d.ts +0 -2
- package/dist/plugins/attributes/scrollIntoView.js +0 -19
- package/dist/plugins/attributes/scrollIntoView.js.map +0 -7
- package/dist/plugins/attributes/show.d.ts +0 -2
- package/dist/plugins/attributes/show.js +0 -19
- package/dist/plugins/attributes/show.js.map +0 -7
- package/dist/plugins/attributes/signals.d.ts +0 -2
- package/dist/plugins/attributes/signals.js +0 -13
- package/dist/plugins/attributes/signals.js.map +0 -7
- package/dist/plugins/attributes/style.d.ts +0 -2
- package/dist/plugins/attributes/style.js +0 -25
- package/dist/plugins/attributes/style.js.map +0 -7
- package/dist/plugins/attributes/text.d.ts +0 -1
- package/dist/plugins/attributes/text.js +0 -13
- package/dist/plugins/attributes/text.js.map +0 -7
- package/dist/plugins/attributes/viewTransition.d.ts +0 -1
- package/dist/plugins/attributes/viewTransition.js +0 -11
- package/dist/plugins/attributes/viewTransition.js.map +0 -7
- package/dist/plugins/directives/transition-name.d.ts +0 -1
- package/dist/plugins/directives/transition-name.js +0 -11
- package/dist/plugins/directives/transition-name.js.map +0 -7
- package/dist/plugins/directives/trap.d.ts +0 -5
- package/dist/plugins/directives/trap.js +0 -48
- package/dist/plugins/directives/trap.js.map +0 -7
- package/dist/sigmx.auto.js +0 -5
- package/dist/utils/object.d.ts +0 -9
- package/dist/utils/object.js +0 -26
- package/dist/utils/object.js.map +0 -7
- package/dist/utils/text.d.ts +0 -7
- package/dist/utils/text.js +0 -15
- package/dist/utils/text.js.map +0 -7
- package/dist/utils/timing.d.ts +0 -14
- package/dist/utils/timing.js +0 -58
- package/dist/utils/timing.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/functions/range-map.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { act } from '../def.js';\n\n/** Map `v` from [inMin, inMax] onto [outMin, outMax]; optionally clamp and round. */\nexport const fit = act(\n 'fit',\n (_, v: number, inMin: number, inMax: number, outMin: number, outMax: number, clamp = false, round = false) => {\n let t = inMax === inMin ? 0 : (v - inMin) / (inMax - inMin);\n if (clamp) t = Math.min(1, Math.max(0, t));\n const out = outMin + t * (outMax - outMin);\n return round ? Math.round(out) : out;\n },\n);\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,WAAW;AAGb,MAAM,MAAM;AAAA,EACjB;AAAA,EACA,CAAC,GAAG,GAAW,OAAe,OAAe,QAAgB,QAAgB,QAAQ,OAAO,QAAQ,UAAU;AAC5G,QAAI,IAAI,UAAU,QAAQ,KAAK,IAAI,UAAU,QAAQ;AACrD,QAAI,MAAO,KAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACzC,UAAM,MAAM,SAAS,KAAK,SAAS;AACnC,WAAO,QAAQ,KAAK,MAAM,GAAG,IAAI;AAAA,EACnC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,9 +9,7 @@ export type RequestOptions = {
|
|
|
9
9
|
/** Explicit body instead of signals. */
|
|
10
10
|
payload?: unknown;
|
|
11
11
|
/** 'replace' (default) aborts an earlier request with the same method and URL; 'none' lets them overlap. */
|
|
12
|
-
abort?: 'replace' | 'none'
|
|
13
|
-
/** Keep the connection open while the tab is hidden. Default: true except for GET streams. */
|
|
14
|
-
openWhenHidden?: boolean;
|
|
12
|
+
abort?: 'replace' | 'none';
|
|
15
13
|
/** Reconnect after a stream closes normally (long-lived event streams). */
|
|
16
14
|
reconnect?: boolean;
|
|
17
15
|
retry?: {
|
|
@@ -22,6 +20,12 @@ export type RequestOptions = {
|
|
|
22
20
|
onStatusError?: boolean;
|
|
23
21
|
};
|
|
24
22
|
};
|
|
23
|
+
/** What a request resolves with: the last response that was applied (undefined when nothing was sent). */
|
|
24
|
+
export type RequestResult = {
|
|
25
|
+
url: string;
|
|
26
|
+
status: number;
|
|
27
|
+
redirected: boolean;
|
|
28
|
+
} | undefined;
|
|
25
29
|
/** `@get(url, options)`: signals travel in the `sigmx` query parameter. */
|
|
26
30
|
export declare const httpGet: import("../../kernel/contracts.js").ActionPlugin;
|
|
27
31
|
export declare const httpPost: import("../../kernel/contracts.js").ActionPlugin;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { untracked } from "../../kernel/index.js";
|
|
2
2
|
import { camel } from "../../lib/casing.js";
|
|
3
3
|
import { parseFields, readEvents } from "../../lib/sse.js";
|
|
4
|
+
import { act } from "../def.js";
|
|
4
5
|
const inflight = /* @__PURE__ */ new Map();
|
|
5
6
|
let seq = 0;
|
|
6
7
|
const sleep = (ms, signal) => new Promise((resolve) => {
|
|
8
|
+
if (signal.aborted) return resolve();
|
|
7
9
|
const t = setTimeout(resolve, ms);
|
|
8
|
-
signal.addEventListener(
|
|
10
|
+
signal.addEventListener(
|
|
11
|
+
"abort",
|
|
12
|
+
() => {
|
|
13
|
+
clearTimeout(t);
|
|
14
|
+
resolve();
|
|
15
|
+
},
|
|
16
|
+
{ once: true }
|
|
17
|
+
);
|
|
9
18
|
});
|
|
10
|
-
const untilVisible = () => new Promise((resolve) => document.addEventListener("visibilitychange", () => !document.hidden && resolve(), { once: true }));
|
|
11
19
|
const headerArgs = (res, names, data) => {
|
|
12
20
|
for (const n of names) {
|
|
13
21
|
const v = res.headers.get(`sigmx-${n}`);
|
|
@@ -15,128 +23,125 @@ const headerArgs = (res, names, data) => {
|
|
|
15
23
|
}
|
|
16
24
|
return data;
|
|
17
25
|
};
|
|
18
|
-
const runScript = (text) => {
|
|
19
|
-
const s = document.createElement("script");
|
|
20
|
-
s.text = text;
|
|
21
|
-
document.head.append(s);
|
|
22
|
-
s.remove();
|
|
23
|
-
};
|
|
24
26
|
const send = async (method, ctx, url, o = {}) => {
|
|
25
27
|
const { el, evt, store, runtime, error } = ctx;
|
|
26
28
|
if (!url) throw error(`@${method.toLowerCase()} needs a URL`);
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
+
const u = new URL(url, location.href);
|
|
30
|
+
const key = `${method} ${u.href}`;
|
|
31
|
+
const hasBody = method !== "GET" && method !== "DELETE";
|
|
32
|
+
const headers = new Headers({ Accept: "text/event-stream, text/html, application/json", "Sigmx-Request": "true" });
|
|
33
|
+
for (const [k, v] of new Headers(o.headers)) headers.set(k, v);
|
|
34
|
+
let body;
|
|
35
|
+
const contentType = (t) => {
|
|
36
|
+
if (hasBody && !headers.has("Content-Type")) headers.set("Content-Type", t);
|
|
37
|
+
};
|
|
38
|
+
if ((o.contentType ?? "json") === "json") {
|
|
39
|
+
const json = JSON.stringify(o.payload ?? untracked(() => store.snapshot(o.filter ?? { exclude: /(^|\.)_/ })));
|
|
40
|
+
if (hasBody) {
|
|
41
|
+
body = json;
|
|
42
|
+
contentType("application/json");
|
|
43
|
+
} else u.searchParams.set("sigmx", json);
|
|
44
|
+
} else {
|
|
45
|
+
const form = o.selector ? document.querySelector(o.selector) : el.closest("form");
|
|
46
|
+
if (!form) throw error("no form found", { selector: o.selector });
|
|
47
|
+
if (!form.noValidate && !form.checkValidity()) {
|
|
48
|
+
form.reportValidity();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const submitter = evt instanceof SubmitEvent ? evt.submitter : el instanceof HTMLButtonElement && el.form === form && el.type === "submit" ? el : null;
|
|
52
|
+
const fd = new FormData(form, submitter);
|
|
53
|
+
const params = new URLSearchParams(fd);
|
|
54
|
+
if (!hasBody) for (const [k, v] of params) u.searchParams.append(k, v);
|
|
55
|
+
else if (form.enctype === "multipart/form-data") body = fd;
|
|
56
|
+
else {
|
|
57
|
+
body = params;
|
|
58
|
+
contentType("application/x-www-form-urlencoded");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const ac = new AbortController();
|
|
29
62
|
if (o.abort !== "none") {
|
|
30
63
|
inflight.get(key)?.abort();
|
|
31
64
|
inflight.set(key, ac);
|
|
32
65
|
}
|
|
33
|
-
ctx.cleanup(() => ac.abort());
|
|
66
|
+
const forget = ctx.cleanup(() => ac.abort());
|
|
34
67
|
const rid = ++seq;
|
|
35
|
-
const emit = (type, extra
|
|
36
|
-
const retry = { attempts: 5, interval: 1e3, factor: 2, max: 3e4,
|
|
37
|
-
const pauseWhenHidden = !(o.openWhenHidden ?? method !== "GET");
|
|
38
|
-
const bodyAllowed = method !== "GET" && method !== "DELETE";
|
|
39
|
-
const build = () => {
|
|
40
|
-
const u = new URL(url, location.href);
|
|
41
|
-
const headers = {
|
|
42
|
-
Accept: "text/event-stream, text/html, application/json",
|
|
43
|
-
"Sigmx-Request": "true",
|
|
44
|
-
...o.headers
|
|
45
|
-
};
|
|
46
|
-
let body;
|
|
47
|
-
if ((o.contentType ?? "json") === "json") {
|
|
48
|
-
const payload = o.payload ?? untracked(() => store.snapshot(o.filter ?? { exclude: /(^|\.)_/ }));
|
|
49
|
-
const json = JSON.stringify(payload);
|
|
50
|
-
if (bodyAllowed) {
|
|
51
|
-
body = json;
|
|
52
|
-
headers["Content-Type"] ??= "application/json";
|
|
53
|
-
} else u.searchParams.set("sigmx", json);
|
|
54
|
-
} else {
|
|
55
|
-
const form = o.selector ? document.querySelector(o.selector) : el.closest("form");
|
|
56
|
-
if (!form) throw error("no form found", { selector: o.selector });
|
|
57
|
-
if (!form.noValidate && !form.checkValidity()) {
|
|
58
|
-
form.reportValidity();
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const submitter = evt instanceof SubmitEvent ? evt.submitter : el instanceof HTMLButtonElement ? el : null;
|
|
62
|
-
const fd = new FormData(form, submitter);
|
|
63
|
-
const multipart = form.enctype === "multipart/form-data";
|
|
64
|
-
if (bodyAllowed) {
|
|
65
|
-
body = multipart ? fd : new URLSearchParams(fd);
|
|
66
|
-
if (!multipart) headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
67
|
-
} else {
|
|
68
|
-
for (const [k, v] of new URLSearchParams(fd)) u.searchParams.append(k, v);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return { url: u.toString(), init: { method, headers, body } };
|
|
72
|
-
};
|
|
73
|
-
const route = (event, data) => {
|
|
74
|
-
const fields = parseFields(data);
|
|
75
|
-
runtime.emit("server-event", { el, event, data: fields });
|
|
76
|
-
runtime.handle(event, fields);
|
|
77
|
-
};
|
|
68
|
+
const emit = (type, extra) => runtime.emit("fetch", { el, type, method, url, rid, ...extra });
|
|
69
|
+
const retry = { attempts: 5, interval: 1e3, factor: 2, max: 3e4, ...o.retry };
|
|
78
70
|
let attempt = 0;
|
|
79
71
|
let wait = retry.interval;
|
|
80
72
|
let lastId;
|
|
73
|
+
let last;
|
|
74
|
+
let applyError;
|
|
75
|
+
const apply = (fn) => {
|
|
76
|
+
try {
|
|
77
|
+
fn();
|
|
78
|
+
} catch (e) {
|
|
79
|
+
applyError = e;
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
81
83
|
const backoff = async () => {
|
|
82
84
|
if (attempt++ >= retry.attempts) throw new Error("retries exhausted");
|
|
83
|
-
emit("retrying", { attempt });
|
|
84
85
|
await sleep(wait, ac.signal);
|
|
85
86
|
wait = Math.min(wait * retry.factor, retry.max);
|
|
86
87
|
};
|
|
87
88
|
emit("started");
|
|
88
89
|
try {
|
|
89
90
|
while (!ac.signal.aborted) {
|
|
90
|
-
|
|
91
|
-
if (!req) return;
|
|
92
|
-
if (lastId) req.init.headers["Last-Event-ID"] = lastId;
|
|
93
|
-
const hide = new AbortController();
|
|
94
|
-
const onHide = () => document.hidden && hide.abort();
|
|
95
|
-
if (pauseWhenHidden) document.addEventListener("visibilitychange", onHide);
|
|
91
|
+
if (lastId) headers.set("Last-Event-ID", lastId);
|
|
96
92
|
try {
|
|
97
|
-
const res = await fetch(
|
|
93
|
+
const res = await fetch(u.href, { method, headers, body, signal: ac.signal });
|
|
94
|
+
last = { url: res.url, status: res.status, redirected: res.redirected };
|
|
98
95
|
const ct = res.headers.get("content-type") ?? "";
|
|
99
|
-
if (res.
|
|
96
|
+
if (!res.ok) {
|
|
100
97
|
emit("error", { status: res.status });
|
|
101
|
-
if (!retry.onStatusError) return;
|
|
98
|
+
if (!retry.onStatusError) return last;
|
|
102
99
|
await backoff();
|
|
103
100
|
continue;
|
|
104
101
|
}
|
|
105
|
-
if (
|
|
102
|
+
if (!res.body) return last;
|
|
106
103
|
if (ct.includes("text/event-stream")) {
|
|
107
104
|
attempt = 0;
|
|
108
105
|
wait = retry.interval;
|
|
109
106
|
await readEvents(res.body, (e) => {
|
|
110
107
|
if (e.id !== void 0) lastId = e.id;
|
|
111
108
|
if (e.retry) wait = retry.interval = e.retry;
|
|
112
|
-
|
|
109
|
+
const data = parseFields(e.data);
|
|
110
|
+
apply(() => {
|
|
111
|
+
runtime.emit("server-event", { el, event: e.event, data });
|
|
112
|
+
runtime.handle(e.event, data);
|
|
113
|
+
});
|
|
113
114
|
});
|
|
114
|
-
if (!o.reconnect) return;
|
|
115
|
+
if (!o.reconnect) return last;
|
|
115
116
|
await backoff();
|
|
116
117
|
continue;
|
|
117
118
|
}
|
|
118
119
|
const text = await res.text();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
apply(() => {
|
|
121
|
+
if (ct.includes("text/html"))
|
|
122
|
+
runtime.handle("patch-elements", headerArgs(res, ["selector", "mode"], { elements: text }));
|
|
123
|
+
else if (ct.includes("application/json"))
|
|
124
|
+
runtime.handle("patch-signals", headerArgs(res, ["only-if-missing"], { signals: text }));
|
|
125
|
+
});
|
|
126
|
+
return last;
|
|
127
|
+
} catch (e) {
|
|
128
|
+
if (ac.signal.aborted) return last;
|
|
129
|
+
if (applyError) throw e;
|
|
130
|
+
await backoff();
|
|
129
131
|
}
|
|
130
132
|
}
|
|
133
|
+
return last;
|
|
131
134
|
} catch (e) {
|
|
132
135
|
emit("error", { message: e?.message });
|
|
133
136
|
throw error(`${method} ${url}: ${e?.message ?? e}`);
|
|
134
137
|
} finally {
|
|
135
|
-
|
|
138
|
+
ac.abort();
|
|
139
|
+
forget();
|
|
140
|
+
emit("finished", last);
|
|
136
141
|
if (inflight.get(key) === ac) inflight.delete(key);
|
|
137
142
|
}
|
|
138
143
|
};
|
|
139
|
-
const make = (name, method) =>
|
|
144
|
+
const make = (name, method) => act(name, (ctx, url, o) => send(method, ctx, url, o));
|
|
140
145
|
const httpGet = make("get", "GET");
|
|
141
146
|
const httpPost = make("post", "POST");
|
|
142
147
|
const httpPut = make("put", "PUT");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/functions/request.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,
|
|
4
|
+
"sourcesContent": ["import { type ActionCtx, type Filter, untracked } from '../../kernel/index.js';\nimport { camel } from '../../lib/casing.js';\nimport { parseFields, readEvents } from '../../lib/sse.js';\nimport { act } from '../def.js';\n\nexport type RequestOptions = {\n headers?: Record<string, string>;\n /** 'json' (default) sends filtered signals; 'form' serialises the closest (or `selector`) form. */\n contentType?: 'json' | 'form';\n selector?: string;\n /** Which signals to send. Default: everything except paths starting with `_`. */\n filter?: Filter;\n /** Explicit body instead of signals. */\n payload?: unknown;\n /** 'replace' (default) aborts an earlier request with the same method and URL; 'none' lets them overlap. */\n abort?: 'replace' | 'none';\n /** Reconnect after a stream closes normally (long-lived event streams). */\n reconnect?: boolean;\n retry?: { attempts?: number; interval?: number; factor?: number; max?: number; onStatusError?: boolean };\n};\n\n/** What a request resolves with: the last response that was applied (undefined when nothing was sent). */\nexport type RequestResult = { url: string; status: number; redirected: boolean } | undefined;\n\nconst inflight = new Map<string, AbortController>();\nlet seq = 0;\nconst sleep = (ms: number, signal: AbortSignal) =>\n new Promise<void>((resolve) => {\n if (signal.aborted) return resolve();\n const t = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(t);\n resolve();\n },\n { once: true },\n );\n });\n\n/** Response headers `sigmx-<name>` become camel-cased fields of `data`. */\nconst headerArgs = (res: Response, names: string[], data: Record<string, string>) => {\n for (const n of names) {\n const v = res.headers.get(`sigmx-${n}`);\n if (v) data[camel(n)] = v;\n }\n return data;\n};\n\nconst send = async (method: string, ctx: ActionCtx, url: string, o: RequestOptions = {}): Promise<RequestResult> => {\n const { el, evt, store, runtime, error } = ctx;\n if (!url) throw error(`@${method.toLowerCase()} needs a URL`);\n const u = new URL(url, location.href);\n const key = `${method} ${u.href}`; // resolved, before any signals are appended\n const hasBody = method !== 'GET' && method !== 'DELETE';\n const headers = new Headers({ Accept: 'text/event-stream, text/html, application/json', 'Sigmx-Request': 'true' });\n for (const [k, v] of new Headers(o.headers)) headers.set(k, v);\n let body: BodyInit | undefined;\n const contentType = (t: string) => {\n if (hasBody && !headers.has('Content-Type')) headers.set('Content-Type', t);\n };\n if ((o.contentType ?? 'json') === 'json') {\n const json = JSON.stringify(o.payload ?? untracked(() => store.snapshot(o.filter ?? { exclude: /(^|\\.)_/ })));\n if (hasBody) {\n body = json;\n contentType('application/json');\n } else u.searchParams.set('sigmx', json);\n } else {\n const form = (o.selector ? document.querySelector(o.selector) : el.closest('form')) as HTMLFormElement | null;\n if (!form) throw error('no form found', { selector: o.selector });\n if (!form.noValidate && !form.checkValidity()) {\n form.reportValidity();\n return;\n }\n // Only a real submit button may be the submitter; FormData throws for anything else.\n const submitter =\n evt instanceof SubmitEvent\n ? evt.submitter\n : el instanceof HTMLButtonElement && el.form === form && el.type === 'submit'\n ? el\n : null;\n const fd = new FormData(form, submitter);\n const params = new URLSearchParams(fd as unknown as Record<string, string>);\n if (!hasBody) for (const [k, v] of params) u.searchParams.append(k, v);\n else if (form.enctype === 'multipart/form-data') body = fd;\n else {\n body = params;\n contentType('application/x-www-form-urlencoded');\n }\n }\n\n const ac = new AbortController();\n if (o.abort !== 'none') {\n inflight.get(key)?.abort();\n inflight.set(key, ac);\n }\n const forget = ctx.cleanup(() => ac.abort());\n const rid = ++seq;\n const emit = (type: string, extra?: object) => runtime.emit('fetch', { el, type, method, url, rid, ...extra });\n const retry = { attempts: 5, interval: 1000, factor: 2, max: 30_000, ...o.retry };\n let attempt = 0;\n let wait = retry.interval;\n let lastId: string | undefined;\n let last: RequestResult;\n // Exceptions thrown while applying a response are the page's problem, not the network's: no retry.\n let applyError: unknown;\n const apply = (fn: () => void) => {\n try {\n fn();\n } catch (e) {\n applyError = e;\n throw e;\n }\n };\n const backoff = async () => {\n if (attempt++ >= retry.attempts) throw new Error('retries exhausted');\n await sleep(wait, ac.signal);\n wait = Math.min(wait * retry.factor, retry.max);\n };\n\n emit('started');\n try {\n while (!ac.signal.aborted) {\n if (lastId) headers.set('Last-Event-ID', lastId);\n try {\n const res = await fetch(u.href, { method, headers, body, signal: ac.signal });\n last = { url: res.url, status: res.status, redirected: res.redirected };\n const ct = res.headers.get('content-type') ?? '';\n if (!res.ok) {\n emit('error', { status: res.status });\n if (!retry.onStatusError) return last;\n await backoff();\n continue;\n }\n if (!res.body) return last;\n if (ct.includes('text/event-stream')) {\n attempt = 0;\n wait = retry.interval;\n await readEvents(res.body, (e) => {\n if (e.id !== undefined) lastId = e.id;\n if (e.retry) wait = retry.interval = e.retry;\n const data = parseFields(e.data);\n apply(() => {\n runtime.emit('server-event', { el, event: e.event, data });\n runtime.handle(e.event, data);\n });\n });\n if (!o.reconnect) return last;\n await backoff();\n continue;\n }\n const text = await res.text();\n apply(() => {\n if (ct.includes('text/html'))\n runtime.handle('patch-elements', headerArgs(res, ['selector', 'mode'], { elements: text }));\n else if (ct.includes('application/json'))\n runtime.handle('patch-signals', headerArgs(res, ['only-if-missing'], { signals: text }));\n });\n return last;\n } catch (e) {\n if (ac.signal.aborted) return last;\n if (applyError) throw e;\n await backoff();\n }\n }\n return last;\n } catch (e: any) {\n emit('error', { message: e?.message });\n throw error(`${method} ${url}: ${e?.message ?? e}`);\n } finally {\n ac.abort(); // releases a still-open body and any pending backoff\n forget();\n emit('finished', last);\n if (inflight.get(key) === ac) inflight.delete(key);\n }\n};\n\nconst make = (name: string, method: string) =>\n act(name, (ctx, url: string, o?: RequestOptions) => send(method, ctx, url, o));\n\n/** `@get(url, options)`: signals travel in the `sigmx` query parameter. */\nexport const httpGet = make('get', 'GET');\nexport const httpPost = make('post', 'POST');\nexport const httpPut = make('put', 'PUT');\nexport const httpPatch = make('patch', 'PATCH');\nexport const httpDelete = make('delete', 'DELETE');\n"],
|
|
5
|
+
"mappings": "AAAA,SAAsC,iBAAiB;AACvD,SAAS,aAAa;AACtB,SAAS,aAAa,kBAAkB;AACxC,SAAS,WAAW;AAqBpB,MAAM,WAAW,oBAAI,IAA6B;AAClD,IAAI,MAAM;AACV,MAAM,QAAQ,CAAC,IAAY,WACzB,IAAI,QAAc,CAAC,YAAY;AAC7B,MAAI,OAAO,QAAS,QAAO,QAAQ;AACnC,QAAM,IAAI,WAAW,SAAS,EAAE;AAChC,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AACJ,mBAAa,CAAC;AACd,cAAQ;AAAA,IACV;AAAA,IACA,EAAE,MAAM,KAAK;AAAA,EACf;AACF,CAAC;AAGH,MAAM,aAAa,CAAC,KAAe,OAAiB,SAAiC;AACnF,aAAW,KAAK,OAAO;AACrB,UAAM,IAAI,IAAI,QAAQ,IAAI,SAAS,CAAC,EAAE;AACtC,QAAI,EAAG,MAAK,MAAM,CAAC,CAAC,IAAI;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,MAAM,OAAO,OAAO,QAAgB,KAAgB,KAAa,IAAoB,CAAC,MAA8B;AAClH,QAAM,EAAE,IAAI,KAAK,OAAO,SAAS,MAAM,IAAI;AAC3C,MAAI,CAAC,IAAK,OAAM,MAAM,IAAI,OAAO,YAAY,CAAC,cAAc;AAC5D,QAAM,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI;AACpC,QAAM,MAAM,GAAG,MAAM,IAAI,EAAE,IAAI;AAC/B,QAAM,UAAU,WAAW,SAAS,WAAW;AAC/C,QAAM,UAAU,IAAI,QAAQ,EAAE,QAAQ,kDAAkD,iBAAiB,OAAO,CAAC;AACjH,aAAW,CAAC,GAAG,CAAC,KAAK,IAAI,QAAQ,EAAE,OAAO,EAAG,SAAQ,IAAI,GAAG,CAAC;AAC7D,MAAI;AACJ,QAAM,cAAc,CAAC,MAAc;AACjC,QAAI,WAAW,CAAC,QAAQ,IAAI,cAAc,EAAG,SAAQ,IAAI,gBAAgB,CAAC;AAAA,EAC5E;AACA,OAAK,EAAE,eAAe,YAAY,QAAQ;AACxC,UAAM,OAAO,KAAK,UAAU,EAAE,WAAW,UAAU,MAAM,MAAM,SAAS,EAAE,UAAU,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC;AAC5G,QAAI,SAAS;AACX,aAAO;AACP,kBAAY,kBAAkB;AAAA,IAChC,MAAO,GAAE,aAAa,IAAI,SAAS,IAAI;AAAA,EACzC,OAAO;AACL,UAAM,OAAQ,EAAE,WAAW,SAAS,cAAc,EAAE,QAAQ,IAAI,GAAG,QAAQ,MAAM;AACjF,QAAI,CAAC,KAAM,OAAM,MAAM,iBAAiB,EAAE,UAAU,EAAE,SAAS,CAAC;AAChE,QAAI,CAAC,KAAK,cAAc,CAAC,KAAK,cAAc,GAAG;AAC7C,WAAK,eAAe;AACpB;AAAA,IACF;AAEA,UAAM,YACJ,eAAe,cACX,IAAI,YACJ,cAAc,qBAAqB,GAAG,SAAS,QAAQ,GAAG,SAAS,WACjE,KACA;AACR,UAAM,KAAK,IAAI,SAAS,MAAM,SAAS;AACvC,UAAM,SAAS,IAAI,gBAAgB,EAAuC;AAC1E,QAAI,CAAC,QAAS,YAAW,CAAC,GAAG,CAAC,KAAK,OAAQ,GAAE,aAAa,OAAO,GAAG,CAAC;AAAA,aAC5D,KAAK,YAAY,sBAAuB,QAAO;AAAA,SACnD;AACH,aAAO;AACP,kBAAY,mCAAmC;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,KAAK,IAAI,gBAAgB;AAC/B,MAAI,EAAE,UAAU,QAAQ;AACtB,aAAS,IAAI,GAAG,GAAG,MAAM;AACzB,aAAS,IAAI,KAAK,EAAE;AAAA,EACtB;AACA,QAAM,SAAS,IAAI,QAAQ,MAAM,GAAG,MAAM,CAAC;AAC3C,QAAM,MAAM,EAAE;AACd,QAAM,OAAO,CAAC,MAAc,UAAmB,QAAQ,KAAK,SAAS,EAAE,IAAI,MAAM,QAAQ,KAAK,KAAK,GAAG,MAAM,CAAC;AAC7G,QAAM,QAAQ,EAAE,UAAU,GAAG,UAAU,KAAM,QAAQ,GAAG,KAAK,KAAQ,GAAG,EAAE,MAAM;AAChF,MAAI,UAAU;AACd,MAAI,OAAO,MAAM;AACjB,MAAI;AACJ,MAAI;AAEJ,MAAI;AACJ,QAAM,QAAQ,CAAC,OAAmB;AAChC,QAAI;AACF,SAAG;AAAA,IACL,SAAS,GAAG;AACV,mBAAa;AACb,YAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,UAAU,YAAY;AAC1B,QAAI,aAAa,MAAM,SAAU,OAAM,IAAI,MAAM,mBAAmB;AACpE,UAAM,MAAM,MAAM,GAAG,MAAM;AAC3B,WAAO,KAAK,IAAI,OAAO,MAAM,QAAQ,MAAM,GAAG;AAAA,EAChD;AAEA,OAAK,SAAS;AACd,MAAI;AACF,WAAO,CAAC,GAAG,OAAO,SAAS;AACzB,UAAI,OAAQ,SAAQ,IAAI,iBAAiB,MAAM;AAC/C,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAS,MAAM,QAAQ,GAAG,OAAO,CAAC;AAC5E,eAAO,EAAE,KAAK,IAAI,KAAK,QAAQ,IAAI,QAAQ,YAAY,IAAI,WAAW;AACtE,cAAM,KAAK,IAAI,QAAQ,IAAI,cAAc,KAAK;AAC9C,YAAI,CAAC,IAAI,IAAI;AACX,eAAK,SAAS,EAAE,QAAQ,IAAI,OAAO,CAAC;AACpC,cAAI,CAAC,MAAM,cAAe,QAAO;AACjC,gBAAM,QAAQ;AACd;AAAA,QACF;AACA,YAAI,CAAC,IAAI,KAAM,QAAO;AACtB,YAAI,GAAG,SAAS,mBAAmB,GAAG;AACpC,oBAAU;AACV,iBAAO,MAAM;AACb,gBAAM,WAAW,IAAI,MAAM,CAAC,MAAM;AAChC,gBAAI,EAAE,OAAO,OAAW,UAAS,EAAE;AACnC,gBAAI,EAAE,MAAO,QAAO,MAAM,WAAW,EAAE;AACvC,kBAAM,OAAO,YAAY,EAAE,IAAI;AAC/B,kBAAM,MAAM;AACV,sBAAQ,KAAK,gBAAgB,EAAE,IAAI,OAAO,EAAE,OAAO,KAAK,CAAC;AACzD,sBAAQ,OAAO,EAAE,OAAO,IAAI;AAAA,YAC9B,CAAC;AAAA,UACH,CAAC;AACD,cAAI,CAAC,EAAE,UAAW,QAAO;AACzB,gBAAM,QAAQ;AACd;AAAA,QACF;AACA,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,cAAM,MAAM;AACV,cAAI,GAAG,SAAS,WAAW;AACzB,oBAAQ,OAAO,kBAAkB,WAAW,KAAK,CAAC,YAAY,MAAM,GAAG,EAAE,UAAU,KAAK,CAAC,CAAC;AAAA,mBACnF,GAAG,SAAS,kBAAkB;AACrC,oBAAQ,OAAO,iBAAiB,WAAW,KAAK,CAAC,iBAAiB,GAAG,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,QAC3F,CAAC;AACD,eAAO;AAAA,MACT,SAAS,GAAG;AACV,YAAI,GAAG,OAAO,QAAS,QAAO;AAC9B,YAAI,WAAY,OAAM;AACtB,cAAM,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO;AAAA,EACT,SAAS,GAAQ;AACf,SAAK,SAAS,EAAE,SAAS,GAAG,QAAQ,CAAC;AACrC,UAAM,MAAM,GAAG,MAAM,IAAI,GAAG,KAAK,GAAG,WAAW,CAAC,EAAE;AAAA,EACpD,UAAE;AACA,OAAG,MAAM;AACT,WAAO;AACP,SAAK,YAAY,IAAI;AACrB,QAAI,SAAS,IAAI,GAAG,MAAM,GAAI,UAAS,OAAO,GAAG;AAAA,EACnD;AACF;AAEA,MAAM,OAAO,CAAC,MAAc,WAC1B,IAAI,MAAM,CAAC,KAAK,KAAa,MAAuB,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC;AAGxE,MAAM,UAAU,KAAK,OAAO,KAAK;AACjC,MAAM,WAAW,KAAK,QAAQ,MAAM;AACpC,MAAM,UAAU,KAAK,OAAO,KAAK;AACjC,MAAM,YAAY,KAAK,SAAS,OAAO;AACvC,MAAM,aAAa,KAAK,UAAU,QAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { untracked } from "../../kernel/index.js";
|
|
2
|
+
import { act } from "../def.js";
|
|
3
|
+
const peek = act("peek", (_, fn) => typeof fn === "function" ? untracked(fn) : fn);
|
|
3
4
|
export {
|
|
4
5
|
peek
|
|
5
6
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/functions/untracked-read.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { untracked } from '../../kernel/index.js';\nimport { act } from '../def.js';\n\n/** `@peek(() => $x)` reads signals without subscribing the surrounding effect. */\nexport const peek = act('peek', (_, fn: unknown) => (typeof fn === 'function' ? untracked(fn as () => unknown) : fn));\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,WAAW;AAGb,MAAM,OAAO,IAAI,QAAQ,CAAC,GAAG,OAAiB,OAAO,OAAO,aAAa,UAAU,EAAmB,IAAI,EAAG;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,8 +4,8 @@ export type Socket = {
|
|
|
4
4
|
readonly socket: WebSocket;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
* `@ws(
|
|
8
|
-
*
|
|
9
|
-
* `{ send, close, socket }`;
|
|
7
|
+
* `@ws(url, { protocols })` opens a WebSocket whose messages use the server-event wire format
|
|
8
|
+
* (`event <name>` and `data <key> <value>` lines, blank-line separated) and routes them to the
|
|
9
|
+
* same handlers as fetched streams. Returns `{ send, close, socket }`; closed when the element unmounts.
|
|
10
10
|
*/
|
|
11
11
|
export declare const websocket: import("../../kernel/contracts.js").ActionPlugin;
|
|
@@ -1,34 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { parseBlock, parseFields } from "../../lib/sse.js";
|
|
2
|
+
import { act } from "../def.js";
|
|
3
|
+
const websocket = act(
|
|
4
|
+
"ws",
|
|
5
|
+
({ el, runtime, cleanup }, url, o = {}) => {
|
|
5
6
|
const socket = new WebSocket(new URL(url, location.href.replace(/^http/, "ws")), o.protocols);
|
|
6
7
|
socket.onmessage = (m) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const v = line.slice(i + 1).trimStart();
|
|
15
|
-
if (field === "event") event = v;
|
|
16
|
-
else if (field === "data") {
|
|
17
|
-
const j = v.indexOf(" ");
|
|
18
|
-
const k = j < 0 ? v : v.slice(0, j);
|
|
19
|
-
const val = j < 0 ? "" : v.slice(j + 1);
|
|
20
|
-
data[k] = k in data ? `${data[k]}
|
|
21
|
-
${val}` : val;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
runtime.emit("server-event", { el, event, data });
|
|
25
|
-
runtime.handle(event, data);
|
|
8
|
+
if (typeof m.data !== "string") return;
|
|
9
|
+
for (const block of m.data.split(/(?:\r?\n){2,}/)) {
|
|
10
|
+
const e = parseBlock(block);
|
|
11
|
+
if (!e) continue;
|
|
12
|
+
const data = parseFields(e.data);
|
|
13
|
+
runtime.emit("server-event", { el, event: e.event, data });
|
|
14
|
+
runtime.handle(e.event, data);
|
|
26
15
|
}
|
|
27
16
|
};
|
|
28
17
|
cleanup(() => socket.close());
|
|
29
|
-
return {
|
|
18
|
+
return {
|
|
19
|
+
send: (d) => socket.send(typeof d === "string" ? d : JSON.stringify(d)),
|
|
20
|
+
close: () => socket.close(),
|
|
21
|
+
socket
|
|
22
|
+
};
|
|
30
23
|
}
|
|
31
|
-
|
|
24
|
+
);
|
|
32
25
|
export {
|
|
33
26
|
websocket
|
|
34
27
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/functions/websocket.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { parseBlock, parseFields } from '../../lib/sse.js';\nimport { act } from '../def.js';\n\nexport type Socket = { send(data: unknown): void; close(): void; readonly socket: WebSocket };\n\n/**\n * `@ws(url, { protocols })` opens a WebSocket whose messages use the server-event wire format\n * (`event <name>` and `data <key> <value>` lines, blank-line separated) and routes them to the\n * same handlers as fetched streams. Returns `{ send, close, socket }`; closed when the element unmounts.\n */\nexport const websocket = act(\n 'ws',\n ({ el, runtime, cleanup }, url: string, o: { protocols?: string | string[] } = {}): Socket => {\n const socket = new WebSocket(new URL(url, location.href.replace(/^http/, 'ws')), o.protocols);\n socket.onmessage = (m) => {\n if (typeof m.data !== 'string') return; // binary frames are not server events\n for (const block of m.data.split(/(?:\\r?\\n){2,}/)) {\n const e = parseBlock(block);\n if (!e) continue;\n const data = parseFields(e.data);\n runtime.emit('server-event', { el, event: e.event, data });\n runtime.handle(e.event, data);\n }\n };\n cleanup(() => socket.close());\n return {\n send: (d) => socket.send(typeof d === 'string' ? d : JSON.stringify(d)),\n close: () => socket.close(),\n socket,\n };\n },\n);\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY,mBAAmB;AACxC,SAAS,WAAW;AASb,MAAM,YAAY;AAAA,EACvB;AAAA,EACA,CAAC,EAAE,IAAI,SAAS,QAAQ,GAAG,KAAa,IAAuC,CAAC,MAAc;AAC5F,UAAM,SAAS,IAAI,UAAU,IAAI,IAAI,KAAK,SAAS,KAAK,QAAQ,SAAS,IAAI,CAAC,GAAG,EAAE,SAAS;AAC5F,WAAO,YAAY,CAAC,MAAM;AACxB,UAAI,OAAO,EAAE,SAAS,SAAU;AAChC,iBAAW,SAAS,EAAE,KAAK,MAAM,eAAe,GAAG;AACjD,cAAM,IAAI,WAAW,KAAK;AAC1B,YAAI,CAAC,EAAG;AACR,cAAM,OAAO,YAAY,EAAE,IAAI;AAC/B,gBAAQ,KAAK,gBAAgB,EAAE,IAAI,OAAO,EAAE,OAAO,KAAK,CAAC;AACzD,gBAAQ,OAAO,EAAE,OAAO,IAAI;AAAA,MAC9B;AAAA,IACF;AACA,YAAQ,MAAM,OAAO,MAAM,CAAC;AAC5B,WAAO;AAAA,MACL,MAAM,CAAC,MAAM,OAAO,KAAK,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,CAAC,CAAC;AAAA,MACtE,OAAO,MAAM,OAAO,MAAM;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,52 +1,50 @@
|
|
|
1
1
|
export { attr } from './directives/attribute-sync.js';
|
|
2
|
-
export {
|
|
2
|
+
export { boost } from './directives/boost.js';
|
|
3
|
+
export { indicator } from './directives/busy-flag.js';
|
|
3
4
|
export { className } from './directives/class-toggle.js';
|
|
5
|
+
export { cloak } from './directives/cloak.js';
|
|
6
|
+
export { collapse } from './directives/collapse.js';
|
|
7
|
+
export { signals } from './directives/declare.js';
|
|
4
8
|
export { computed } from './directives/derive.js';
|
|
5
|
-
export {
|
|
6
|
-
export { effect } from './directives/watch.js';
|
|
7
|
-
export { indicator } from './directives/busy-flag.js';
|
|
8
|
-
export { init } from './directives/on-mount.js';
|
|
9
|
-
export { jsonSignals } from './directives/state-dump.js';
|
|
10
|
-
export { matchMedia } from './directives/media-query.js';
|
|
9
|
+
export { ref } from './directives/element-ref.js';
|
|
11
10
|
export { on } from './directives/event-listener.js';
|
|
12
|
-
export { onIntersect } from './directives/viewport.js';
|
|
13
|
-
export { onInterval } from './directives/timer.js';
|
|
14
11
|
export { onRaf } from './directives/frame-loop.js';
|
|
15
|
-
export {
|
|
12
|
+
export { html } from './directives/html.js';
|
|
13
|
+
export { style } from './directives/inline-style.js';
|
|
14
|
+
export { applyMask, mask } from './directives/mask.js';
|
|
15
|
+
export { matchMedia } from './directives/media-query.js';
|
|
16
|
+
export { init } from './directives/on-mount.js';
|
|
16
17
|
export { onSignalPatch } from './directives/patch-listener.js';
|
|
18
|
+
export { removeMe } from './directives/remove-me.js';
|
|
19
|
+
export { scrollIntoView } from './directives/scroll-to.js';
|
|
20
|
+
export { onResize } from './directives/size-watch.js';
|
|
21
|
+
export { jsonSignals } from './directives/state-dump.js';
|
|
17
22
|
export { persist } from './directives/storage-sync.js';
|
|
23
|
+
export { teleport } from './directives/teleport.js';
|
|
24
|
+
export { text } from './directives/text-content.js';
|
|
25
|
+
export { onInterval } from './directives/timer.js';
|
|
26
|
+
export { transition } from './directives/transition.js';
|
|
27
|
+
export { animate } from './directives/tween.js';
|
|
28
|
+
export { bind } from './directives/two-way-bind.js';
|
|
18
29
|
export { queryString } from './directives/url-params.js';
|
|
19
|
-
export { ref } from './directives/element-ref.js';
|
|
20
30
|
export { replaceUrl } from './directives/url-replace.js';
|
|
21
|
-
export {
|
|
31
|
+
export { customValidity } from './directives/validity.js';
|
|
32
|
+
export { onIntersect } from './directives/viewport.js';
|
|
22
33
|
export { show } from './directives/visibility.js';
|
|
23
|
-
export {
|
|
24
|
-
export { style } from './directives/inline-style.js';
|
|
25
|
-
export { text } from './directives/text-content.js';
|
|
26
|
-
export { viewTransition } from './directives/transition-name.js';
|
|
27
|
-
export { clipboard } from './functions/copy-text.js';
|
|
28
|
-
export { fit } from './functions/range-map.js';
|
|
29
|
-
export { intl } from './functions/locale-format.js';
|
|
30
|
-
export { peek } from './functions/untracked-read.js';
|
|
34
|
+
export { effect } from './directives/watch.js';
|
|
31
35
|
export { setAll } from './functions/bulk-set.js';
|
|
32
36
|
export { toggleAll } from './functions/bulk-toggle.js';
|
|
33
|
-
export {
|
|
34
|
-
export {
|
|
37
|
+
export { confirm } from './functions/confirm.js';
|
|
38
|
+
export { clipboard } from './functions/copy-text.js';
|
|
39
|
+
export { dispatch } from './functions/dispatch.js';
|
|
40
|
+
export { intl } from './functions/locale-format.js';
|
|
41
|
+
export { fit } from './functions/range-map.js';
|
|
35
42
|
export type { RequestOptions } from './functions/request.js';
|
|
43
|
+
export { httpDelete, httpGet, httpPatch, httpPost, httpPut } from './functions/request.js';
|
|
44
|
+
export { peek } from './functions/untracked-read.js';
|
|
45
|
+
export type { Socket } from './functions/websocket.js';
|
|
46
|
+
export { websocket } from './functions/websocket.js';
|
|
36
47
|
export { applyElements } from './server-events/apply-elements.js';
|
|
37
48
|
export { applyState } from './server-events/apply-state.js';
|
|
38
|
-
export { activateScripts, morph, morphInner } from './server-events/morph.js';
|
|
39
49
|
export type { MorphOptions } from './server-events/morph.js';
|
|
40
|
-
export {
|
|
41
|
-
export { cloak } from './directives/cloak.js';
|
|
42
|
-
export { collapse } from './directives/collapse.js';
|
|
43
|
-
export { html } from './directives/html.js';
|
|
44
|
-
export { applyMask, mask } from './directives/mask.js';
|
|
45
|
-
export { removeMe } from './directives/remove-me.js';
|
|
46
|
-
export { teleport } from './directives/teleport.js';
|
|
47
|
-
export { transition } from './directives/transition.js';
|
|
48
|
-
export { trap } from './directives/trap.js';
|
|
49
|
-
export { confirm } from './functions/confirm.js';
|
|
50
|
-
export { dispatch } from './functions/dispatch.js';
|
|
51
|
-
export { websocket } from './functions/websocket.js';
|
|
52
|
-
export type { Socket } from './functions/websocket.js';
|
|
50
|
+
export { activateScripts, morph, morphInner } from './server-events/morph.js';
|