@solidjs/web 2.0.0-rc.2 → 2.0.0-rc.4
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/dist/dev.cjs +433 -72
- package/dist/dev.js +426 -71
- package/dist/server.cjs +39 -21
- package/dist/server.js +40 -23
- package/dist/web.cjs +421 -70
- package/dist/web.js +414 -69
- package/frames/dist/client.cjs +8 -8
- package/frames/dist/client.dev.cjs +8 -8
- package/frames/dist/client.dev.js +8 -8
- package/frames/dist/client.js +8 -8
- package/frames/dist/server.cjs +28 -18
- package/frames/dist/server.js +29 -19
- package/package.json +20 -22
- package/serialization/dist/decode.cjs +3 -3
- package/serialization/dist/decode.js +3 -3
- package/serialization/dist/serialization.cjs +7 -11
- package/serialization/dist/serialization.js +7 -6
- package/serialization/types/index.d.ts +69 -157
- package/serialization/types/serializer-decode.d.ts +89 -112
- package/serialization/types/serializer.d.ts +94 -0
- package/serialization/types-cjs/index.d.cts +69 -157
- package/serialization/types-cjs/serializer-decode.d.cts +89 -112
- package/serialization/types-cjs/serializer.d.cts +94 -0
- package/server-functions/dist/client.cjs +126 -19
- package/server-functions/dist/client.js +123 -19
- package/server-functions/dist/server.cjs +156 -28
- package/server-functions/dist/server.dev.cjs +156 -28
- package/server-functions/dist/server.dev.js +153 -28
- package/server-functions/dist/server.js +153 -28
- package/types/client.d.ts +152 -290
- package/types/constants.d.ts +18 -0
- package/types/cookies.d.ts +31 -75
- package/types/frames/frame-client.d.ts +287 -277
- package/types/frames/frame-container-plugin.d.ts +71 -0
- package/types/frames/frame-sink.d.ts +58 -160
- package/types/frames/frame-transport.d.ts +161 -194
- package/types/frames/serializer-decode.d.ts +159 -0
- package/types/frames/serializer.d.ts +69 -157
- package/types/head.d.ts +16 -0
- package/types/index.d.ts +1 -65
- package/types/index.server.d.ts +125 -0
- package/types/jsx.d.ts +5 -13
- package/types/patch-driver.d.ts +3 -0
- package/types/reconcile.d.ts +1 -0
- package/types/render.d.ts +4 -0
- package/types/response.d.ts +48 -152
- package/types/serializer-decode.d.ts +89 -112
- package/types/serializer.d.ts +69 -157
- package/types/server-functions/client.d.ts +124 -222
- package/types/server-functions/flash.d.ts +10 -30
- package/types/server-functions/registry.d.ts +100 -0
- package/types/server-functions/rich-args.d.ts +1 -10
- package/types/server-functions/server.d.ts +295 -574
- package/types/server-functions/shared.d.ts +155 -458
- package/types/server-mock.d.ts +2 -2
- package/types/server.d.ts +242 -434
- package/types-cjs/client.d.cts +152 -290
- package/types-cjs/constants.d.cts +18 -0
- package/types-cjs/cookies.d.cts +31 -75
- package/types-cjs/frames/frame-client.d.cts +287 -277
- package/types-cjs/frames/frame-container-plugin.d.cts +71 -0
- package/types-cjs/frames/frame-sink.d.cts +58 -160
- package/types-cjs/frames/frame-transport.d.cts +161 -194
- package/types-cjs/frames/serializer-decode.d.cts +159 -0
- package/types-cjs/frames/serializer.d.cts +69 -157
- package/types-cjs/head.d.cts +16 -0
- package/types-cjs/index.d.cts +1 -65
- package/types-cjs/index.server.d.cts +125 -0
- package/types-cjs/jsx.d.cts +5 -13
- package/types-cjs/patch-driver.d.cts +3 -0
- package/types-cjs/reconcile.d.cts +1 -0
- package/types-cjs/render.d.cts +4 -0
- package/types-cjs/response.d.cts +48 -152
- package/types-cjs/serializer-decode.d.cts +89 -112
- package/types-cjs/serializer.d.cts +69 -157
- package/types-cjs/server-functions/client.d.cts +124 -222
- package/types-cjs/server-functions/flash.d.cts +10 -30
- package/types-cjs/server-functions/registry.d.cts +100 -0
- package/types-cjs/server-functions/rich-args.d.cts +1 -10
- package/types-cjs/server-functions/server.d.cts +295 -574
- package/types-cjs/server-functions/shared.d.cts +155 -458
- package/types-cjs/server-mock.d.cts +2 -2
- package/types-cjs/server.d.cts +242 -434
- package/LICENSE +0 -21
- package/types/core.d.ts +0 -9
- package/types-cjs/core.d.cts +0 -9
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Serializer } from "seroval";
|
|
2
|
+
import type { JSONCodecOptions, PluginInfo, SerializerPlugin, SerovalNode } from "./serializer-decode.cjs";
|
|
3
|
+
export { DEFAULT_WEB_PLUGINS, createJSONDataTable, createJSONDeserializer, resolveSerializerPlugins } from "./serializer-decode.cjs";
|
|
4
|
+
export type * from "./serializer-decode.cjs";
|
|
5
|
+
/**
|
|
6
|
+
* Options for `createSerializer`.
|
|
7
|
+
*
|
|
8
|
+
* Integration-facing; may change (see the entry banner).
|
|
9
|
+
*/
|
|
10
|
+
export interface WebSerializerOptions {
|
|
11
|
+
/** Name of the global object the emitted scripts write resolved values into. */
|
|
12
|
+
globalIdentifier: string;
|
|
13
|
+
/** Cross-reference scope id, for isolating multiple streams on one page. */
|
|
14
|
+
scopeId?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Seroval feature bitflags to exclude from output. Defaults to disabling
|
|
17
|
+
* post-ES2017 features (AggregateError, BigInt typed arrays). Outside
|
|
18
|
+
* development, `Error.prototype.stack` is additionally stripped on top of
|
|
19
|
+
* any override — serialized stacks leak server paths to the client.
|
|
20
|
+
*/
|
|
21
|
+
disabledFeatures?: number;
|
|
22
|
+
/** Extra plugins, composed ahead of `DEFAULT_WEB_PLUGINS`. */
|
|
23
|
+
plugins?: SerializerPlugin[];
|
|
24
|
+
/** Receives each emitted script chunk. */
|
|
25
|
+
onData: (result: string) => void;
|
|
26
|
+
onError?: (error: unknown) => void;
|
|
27
|
+
/** Fires once all async values have settled. */
|
|
28
|
+
onDone?: () => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Options for `createHydrationSerializer` — `WebSerializerOptions` minus
|
|
32
|
+
* the knobs hydration pins (`globalIdentifier`, `disabledFeatures`).
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export type HydrationSerializerOptions = Omit<WebSerializerOptions, "globalIdentifier" | "disabledFeatures">;
|
|
36
|
+
/**
|
|
37
|
+
* Options for `serializeJSON`.
|
|
38
|
+
*
|
|
39
|
+
* Integration-facing; may change (see the entry banner).
|
|
40
|
+
*/
|
|
41
|
+
export interface JSONSerializeOptions extends JSONCodecOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Receives each serialized node; `initial` is true for the first chunk
|
|
44
|
+
* (the source value itself). Async values produce additional chunks as
|
|
45
|
+
* they resolve.
|
|
46
|
+
*/
|
|
47
|
+
onParse: (node: SerovalNode, initial: boolean) => void;
|
|
48
|
+
onError?: (error: unknown) => void;
|
|
49
|
+
/** Fires once all async values have settled. */
|
|
50
|
+
onDone?: () => void;
|
|
51
|
+
}
|
|
52
|
+
/** Options for `createJSONSerializer`. */
|
|
53
|
+
export interface JSONSerializerOptions extends JSONCodecOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Receives each keyed record — `initial` is true for a key's first node
|
|
56
|
+
* (the written value itself); async values patch through later records
|
|
57
|
+
* under the same key. The decoding peer is `createJSONDataTable`.
|
|
58
|
+
*/
|
|
59
|
+
onData: (record: {
|
|
60
|
+
key: string;
|
|
61
|
+
node: SerovalNode;
|
|
62
|
+
initial: boolean;
|
|
63
|
+
}) => void;
|
|
64
|
+
onError?: (error: unknown) => void;
|
|
65
|
+
/** Fires once `flush()` has been called and every pending value settled. */
|
|
66
|
+
onDone?: () => void;
|
|
67
|
+
}
|
|
68
|
+
export declare const createPlugin: <Value, Info extends PluginInfo>(plugin: SerializerPlugin<Value, Info>) => SerializerPlugin<Value, Info>;
|
|
69
|
+
export interface OpaqueReference<V = unknown, R = undefined> {
|
|
70
|
+
readonly value: V;
|
|
71
|
+
readonly replacement?: R;
|
|
72
|
+
}
|
|
73
|
+
export declare const OpaqueReference: {
|
|
74
|
+
new <V, R = undefined>(value: V, replacement?: R): OpaqueReference<V, R>;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Creates a streaming Seroval serializer preconfigured with the web plugin
|
|
78
|
+
* set and the default feature policy. Emits JavaScript chunks (through
|
|
79
|
+
* `onData`) that reconstruct the values under `globalIdentifier` when
|
|
80
|
+
* evaluated — the script-injection form of serialization renderers build
|
|
81
|
+
* on. For a JSON-based wire codec (no eval on the receiving side), use
|
|
82
|
+
* `serializeJSON` / `createJSONDeserializer` instead.
|
|
83
|
+
*
|
|
84
|
+
* Integration-facing; may change (see the entry banner).
|
|
85
|
+
*/
|
|
86
|
+
export declare function createSerializer(options: WebSerializerOptions): Serializer;
|
|
87
|
+
export declare function createHydrationSerializer(options: HydrationSerializerOptions): Serializer;
|
|
88
|
+
export declare function getLocalHeaderScript(id?: string): string;
|
|
89
|
+
export declare function serializeJSON(value: unknown, options: JSONSerializeOptions): () => void;
|
|
90
|
+
export declare function createJSONSerializer(options: JSONSerializerOptions): {
|
|
91
|
+
write(key: string, value: unknown): void;
|
|
92
|
+
flush(): void;
|
|
93
|
+
close(): void;
|
|
94
|
+
};
|
|
@@ -18,6 +18,32 @@ function withMeta(fn, meta) {
|
|
|
18
18
|
Object.assign(metadata, meta);
|
|
19
19
|
return fn;
|
|
20
20
|
}
|
|
21
|
+
const SERVER_FUNCTION_INVOKE = Symbol.for("solid.ServerFunctionInvoke");
|
|
22
|
+
const INVOKE_OPTION_REDIRECTS = {
|
|
23
|
+
headers: "Session-dynamic headers belong to the prepareRequest hook, declaration metadata to " + "withMeta(fn, meta), and data belongs in the arguments, where it is serialized, typed, " + "and part of the cache key.",
|
|
24
|
+
method: "The method is declaration-scoped: declare the function with GET(fn).",
|
|
25
|
+
body: "The arguments are the body: pass them in the args array.",
|
|
26
|
+
timeout: "Compose timeouts through `signal` with AbortSignal.timeout(ms) (and AbortSignal.any to " + "combine it with a caller signal)."
|
|
27
|
+
};
|
|
28
|
+
function invoke(fn, options, ...args) {
|
|
29
|
+
const channel = typeof fn === "function" && fn[SERVER_FUNCTION_INVOKE];
|
|
30
|
+
if (!channel) {
|
|
31
|
+
throw new Error(isServerFunction(fn) ? "invoke: this wrapper does not forward the invocation channel " + "(SERVER_FUNCTION_INVOKE). Wrappers that share calls (caches, channels) opt in " + "deliberately — a caller's signal cannot own a wire other callers share. Invoke " + "the underlying reference directly, or use the wrapper's own per-call idioms." : "invoke expects a server function reference (or a wrapper that forwards its " + "invocation channel). Per-call options apply at the transport; for a data " + "layer's calls, use its per-call options instead.");
|
|
32
|
+
}
|
|
33
|
+
if (options === null || typeof options !== "object") {
|
|
34
|
+
throw new Error("invoke's second argument is the invocation options bag: invoke(fn, { signal }, ...args)");
|
|
35
|
+
}
|
|
36
|
+
const picked = {};
|
|
37
|
+
for (const key in options) {
|
|
38
|
+
if (key !== "signal" && key !== "keepalive" && key !== "priority") {
|
|
39
|
+
throw new Error(`\`${key}\` is not an invocation option. ` + (INVOKE_OPTION_REDIRECTS[key] || "Options here are strictly invocation-scoped (they vary between calls of the " + "same function): signal, keepalive, priority."));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (options.signal !== undefined) picked.signal = options.signal;
|
|
43
|
+
if (options.keepalive !== undefined) picked.keepalive = options.keepalive;
|
|
44
|
+
if (options.priority !== undefined) picked.priority = options.priority;
|
|
45
|
+
return channel(args, picked);
|
|
46
|
+
}
|
|
21
47
|
const LIVE_SOURCE = Symbol.for("solid.LiveSource");
|
|
22
48
|
const SERVER_FUNCTION_RPC = Symbol.for("solid.ServerFunctionRPC");
|
|
23
49
|
function provideServerFunctionRPC(rpc) {
|
|
@@ -98,7 +124,23 @@ function stableString(value, seen) {
|
|
|
98
124
|
}
|
|
99
125
|
return out + "}";
|
|
100
126
|
}
|
|
101
|
-
|
|
127
|
+
function serverFunctionAddress(endpoint, id) {
|
|
128
|
+
const mount = endpoint.endsWith("/") ? endpoint.slice(0, -1) : endpoint;
|
|
129
|
+
return `${mount}/${encodeURIComponent(id)}`;
|
|
130
|
+
}
|
|
131
|
+
function parseServerFunctionAddress(pathname, endpoint) {
|
|
132
|
+
const mount = endpoint.endsWith("/") ? endpoint.slice(0, -1) : endpoint;
|
|
133
|
+
if (!pathname.startsWith(mount)) return null;
|
|
134
|
+
const rest = pathname.slice(mount.length);
|
|
135
|
+
if (!rest.startsWith("/")) return null;
|
|
136
|
+
const segment = rest.slice(1);
|
|
137
|
+
if (!segment || segment.includes("/")) return null;
|
|
138
|
+
try {
|
|
139
|
+
return decodeURIComponent(segment);
|
|
140
|
+
} catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
102
144
|
const ERROR_HEADER = "X-Server-Function-Error";
|
|
103
145
|
const ERROR_HEADER_MARKER = "=?1?";
|
|
104
146
|
const NEEDS_ENCODING = /[^\x20-\x7e\xa0-\xff]/;
|
|
@@ -137,7 +179,8 @@ const BodyFormat = {
|
|
|
137
179
|
File: "5",
|
|
138
180
|
ArrayBuffer: "6",
|
|
139
181
|
Uint8Array: "7",
|
|
140
|
-
Json: "8"
|
|
182
|
+
Json: "8",
|
|
183
|
+
Void: "9"
|
|
141
184
|
};
|
|
142
185
|
const JSON_SAFE_DEPTH_LIMIT = 4096;
|
|
143
186
|
const EXIT = {};
|
|
@@ -392,6 +435,7 @@ async function decodeResponsePayload(response, codecOptions) {
|
|
|
392
435
|
|
|
393
436
|
const config = {
|
|
394
437
|
endpoint: "/_server",
|
|
438
|
+
fetch: undefined,
|
|
395
439
|
prepareRequest: undefined,
|
|
396
440
|
responseHandler: undefined,
|
|
397
441
|
serializeArgs: undefined
|
|
@@ -420,6 +464,17 @@ function observeServerFunctionCalls(observer) {
|
|
|
420
464
|
CALL_OBSERVERS.add(observer);
|
|
421
465
|
return () => CALL_OBSERVERS.delete(observer);
|
|
422
466
|
}
|
|
467
|
+
function serverFunctionUrl(id, boundArgs) {
|
|
468
|
+
const address = serverFunctionAddress(config.endpoint, id);
|
|
469
|
+
if (!boundArgs || !boundArgs.length) return address;
|
|
470
|
+
if (!isJSONSafe(boundArgs)) {
|
|
471
|
+
throw new Error("Bound arguments in an action url must be JSON-safe: the server reads them the way it " + "reads a form post's, and that convention has no codec. Pass the value through the " + "function's body, or call the reference instead of rendering a url for it.");
|
|
472
|
+
}
|
|
473
|
+
return `${address}?args=${encodeURIComponent(JSON.stringify(boundArgs))}`;
|
|
474
|
+
}
|
|
475
|
+
function parseServerFunctionUrl(url) {
|
|
476
|
+
return parseServerFunctionAddress(new URL(url, globalThis.location?.href || "http://localhost").pathname, config.endpoint);
|
|
477
|
+
}
|
|
423
478
|
function serializeArguments(args) {
|
|
424
479
|
if (!config.serializeArgs) {
|
|
425
480
|
throw new Error("Server function arguments are sent as JSON by default and these " + "arguments are not JSON-serializable. Call enableRichArguments() " + '(from "@solidjs/web/server-functions/rich-args") once at startup ' + "to send Dates, Maps, Sets, typed arrays, etc. through the codec — " + "or pass a single Blob/FormData/File argument, which has a native " + "HTTP encoding.");
|
|
@@ -429,17 +484,20 @@ function serializeArguments(args) {
|
|
|
429
484
|
function configureServerFunctionsClient({
|
|
430
485
|
endpoint,
|
|
431
486
|
codec,
|
|
487
|
+
fetch,
|
|
432
488
|
prepareRequest,
|
|
433
489
|
responseHandler,
|
|
434
490
|
serializeArgs
|
|
435
491
|
} = {}) {
|
|
436
492
|
if (endpoint !== undefined) config.endpoint = endpoint;
|
|
437
493
|
if (codec !== undefined) configureServerFunctionsCodec(codec);
|
|
494
|
+
if (fetch !== undefined) config.fetch = fetch;
|
|
438
495
|
if (prepareRequest !== undefined) config.prepareRequest = prepareRequest;
|
|
439
496
|
if (responseHandler !== undefined) config.responseHandler = responseHandler;
|
|
440
497
|
if (serializeArgs !== undefined) config.serializeArgs = serializeArgs;
|
|
441
498
|
}
|
|
442
499
|
let INSTANCE = 0;
|
|
500
|
+
const MAX_GET_URL_LENGTH = 2000;
|
|
443
501
|
let rpcProvided = false;
|
|
444
502
|
function provideRPC() {
|
|
445
503
|
if (rpcProvided) return;
|
|
@@ -457,7 +515,6 @@ function serverFunctionFailure(response, value) {
|
|
|
457
515
|
async function createRequest(base, id, instance, options, meta) {
|
|
458
516
|
const headers = {
|
|
459
517
|
...options.headers,
|
|
460
|
-
[FUNCTION_HEADER]: id,
|
|
461
518
|
[INSTANCE_HEADER]: instance
|
|
462
519
|
};
|
|
463
520
|
if (getFlightDataConsumer() && !options.read && (!options.method || options.method.toUpperCase() !== "GET")) {
|
|
@@ -474,10 +531,14 @@ async function createRequest(base, id, instance, options, meta) {
|
|
|
474
531
|
meta
|
|
475
532
|
})) || init;
|
|
476
533
|
}
|
|
477
|
-
|
|
478
|
-
|
|
534
|
+
const send = config.fetch || fetch;
|
|
535
|
+
if (CALL_OBSERVERS.size === 0) return send(base, init);
|
|
536
|
+
const request = new Request(new URL(base, globalThis.location?.href || "http://localhost"), {
|
|
537
|
+
...init,
|
|
538
|
+
body: init.body instanceof ReadableStream ? undefined : init.body
|
|
539
|
+
});
|
|
479
540
|
notifyCallObservers("request", id, instance, request, meta);
|
|
480
|
-
const response = await
|
|
541
|
+
const response = await send(base, init);
|
|
481
542
|
notifyCallObservers("response", id, instance, response, meta);
|
|
482
543
|
return response;
|
|
483
544
|
}
|
|
@@ -562,6 +623,9 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
|
|
|
562
623
|
});
|
|
563
624
|
if (handled !== undefined) return handled;
|
|
564
625
|
}
|
|
626
|
+
if (response.status >= 400 && !response.headers.has(BODY_FORMAT_HEADER)) {
|
|
627
|
+
throw serverFunctionFailure(response, undefined);
|
|
628
|
+
}
|
|
565
629
|
const failed = response.headers.has(ERROR_HEADER) || response.status >= 500;
|
|
566
630
|
if (response.headers.has(SINGLE_FLIGHT_HEADER)) {
|
|
567
631
|
const consumer = getFlightDataConsumer();
|
|
@@ -604,7 +668,7 @@ function createServerReference(id, name, base) {
|
|
|
604
668
|
const metadata = name === undefined ? {} : {
|
|
605
669
|
name
|
|
606
670
|
};
|
|
607
|
-
const
|
|
671
|
+
const run = (args, invokeOptions) => {
|
|
608
672
|
const handler = config.responseHandler;
|
|
609
673
|
if (handler && handler.intercept) {
|
|
610
674
|
const hit = handler.intercept({
|
|
@@ -614,14 +678,18 @@ function createServerReference(id, name, base) {
|
|
|
614
678
|
});
|
|
615
679
|
if (hit !== undefined) return hit;
|
|
616
680
|
}
|
|
617
|
-
return fetchServerFunction(base || config.endpoint, id,
|
|
681
|
+
return fetchServerFunction(base || serverFunctionAddress(config.endpoint, id), id, invokeOptions ? {
|
|
682
|
+
...invokeOptions
|
|
683
|
+
} : {}, args, metadata);
|
|
618
684
|
};
|
|
685
|
+
const fn = (...args) => run(args);
|
|
619
686
|
fn[SERVER_FUNCTION_METADATA] = metadata;
|
|
687
|
+
fn[SERVER_FUNCTION_INVOKE] = run;
|
|
620
688
|
return new Proxy(fn, {
|
|
621
689
|
get(target, prop) {
|
|
622
690
|
if (prop === "id") return id;
|
|
623
691
|
if (prop === "url") {
|
|
624
|
-
return base ||
|
|
692
|
+
return base || serverFunctionAddress(config.endpoint, id);
|
|
625
693
|
}
|
|
626
694
|
return target[prop];
|
|
627
695
|
}
|
|
@@ -636,7 +704,7 @@ function GET(fn) {
|
|
|
636
704
|
const metadata = {
|
|
637
705
|
...getServerFunctionMetadata(fn)
|
|
638
706
|
};
|
|
639
|
-
const
|
|
707
|
+
const run = async (args, invokeOptions) => {
|
|
640
708
|
const handler = config.responseHandler;
|
|
641
709
|
if (handler && handler.intercept) {
|
|
642
710
|
const hit = handler.intercept({
|
|
@@ -646,19 +714,34 @@ function GET(fn) {
|
|
|
646
714
|
});
|
|
647
715
|
if (hit !== undefined) return hit;
|
|
648
716
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
717
|
+
const opts = invokeOptions || {};
|
|
718
|
+
const address = serverFunctionAddress(config.endpoint, id);
|
|
719
|
+
if (!args.length) {
|
|
720
|
+
return fetchServerFunction(address, id, {
|
|
721
|
+
...opts,
|
|
722
|
+
method: "GET"
|
|
723
|
+
}, [], metadata, args);
|
|
724
|
+
}
|
|
725
|
+
const encoded = isJSONSafe(args) ? JSON.stringify(args) : await serializeArguments(args);
|
|
726
|
+
const url = `${address}?args=${encodeURIComponent(encoded)}`;
|
|
727
|
+
const absolute = new URL(url, globalThis.location?.href || "http://localhost").href;
|
|
728
|
+
if (absolute.length > MAX_GET_URL_LENGTH) {
|
|
729
|
+
return fetchServerFunction(address, id, {
|
|
730
|
+
...opts,
|
|
731
|
+
read: true
|
|
732
|
+
}, args, metadata);
|
|
653
733
|
}
|
|
654
|
-
return fetchServerFunction(
|
|
734
|
+
return fetchServerFunction(url, id, {
|
|
735
|
+
...opts,
|
|
655
736
|
method: "GET"
|
|
656
737
|
}, [], metadata, args);
|
|
657
738
|
};
|
|
739
|
+
const wrapped = (...args) => run(args);
|
|
658
740
|
wrapped[SERVER_FUNCTION_METADATA] = metadata;
|
|
741
|
+
wrapped[SERVER_FUNCTION_INVOKE] = run;
|
|
659
742
|
wrapped.id = id;
|
|
660
743
|
Object.defineProperty(wrapped, "url", {
|
|
661
|
-
get: () =>
|
|
744
|
+
get: () => serverFunctionAddress(config.endpoint, id),
|
|
662
745
|
configurable: true
|
|
663
746
|
});
|
|
664
747
|
return withMeta(wrapped, {
|
|
@@ -674,7 +757,7 @@ function live(fn) {
|
|
|
674
757
|
...getServerFunctionMetadata(fn),
|
|
675
758
|
live: true
|
|
676
759
|
};
|
|
677
|
-
const
|
|
760
|
+
const makeIterable = (args, invokeOptions) => {
|
|
678
761
|
const iterable = {
|
|
679
762
|
[LIVE_SOURCE]: true,
|
|
680
763
|
[Symbol.asyncIterator]() {
|
|
@@ -688,6 +771,12 @@ function live(fn) {
|
|
|
688
771
|
done: true,
|
|
689
772
|
value: undefined
|
|
690
773
|
};
|
|
774
|
+
const invokeSignal = invokeOptions && invokeOptions.signal;
|
|
775
|
+
const controller = new AbortController();
|
|
776
|
+
const wireOptions = {
|
|
777
|
+
...invokeOptions,
|
|
778
|
+
signal: invokeSignal ? AbortSignal.any([invokeSignal, controller.signal]) : controller.signal
|
|
779
|
+
};
|
|
691
780
|
const emit = (state, error) => {
|
|
692
781
|
try {
|
|
693
782
|
iterable.onstatus && iterable.onstatus(state, error);
|
|
@@ -709,7 +798,7 @@ function live(fn) {
|
|
|
709
798
|
}
|
|
710
799
|
};
|
|
711
800
|
const callOnce = () => {
|
|
712
|
-
if (metadata.method === "GET") return fn(
|
|
801
|
+
if (metadata.method === "GET") return fn[SERVER_FUNCTION_INVOKE](args, wireOptions);
|
|
713
802
|
const handler = config.responseHandler;
|
|
714
803
|
if (handler && handler.intercept) {
|
|
715
804
|
const hit = handler.intercept({
|
|
@@ -720,6 +809,7 @@ function live(fn) {
|
|
|
720
809
|
if (hit !== undefined) return hit;
|
|
721
810
|
}
|
|
722
811
|
return fetchServerFunction(fn.url, id, {
|
|
812
|
+
...wireOptions,
|
|
723
813
|
read: true
|
|
724
814
|
}, args, metadata, args);
|
|
725
815
|
};
|
|
@@ -734,6 +824,7 @@ function live(fn) {
|
|
|
734
824
|
}();
|
|
735
825
|
if (stopped) {
|
|
736
826
|
closeIt();
|
|
827
|
+
controller.abort();
|
|
737
828
|
return DONE;
|
|
738
829
|
}
|
|
739
830
|
emit("connected");
|
|
@@ -747,7 +838,13 @@ function live(fn) {
|
|
|
747
838
|
attempts = 0;
|
|
748
839
|
return r;
|
|
749
840
|
} catch (error) {
|
|
841
|
+
if (stopped) return DONE;
|
|
750
842
|
if (!connected) throw error;
|
|
843
|
+
if (invokeSignal && invokeSignal.aborted) {
|
|
844
|
+
stopped = true;
|
|
845
|
+
emitClosed(error);
|
|
846
|
+
throw error;
|
|
847
|
+
}
|
|
751
848
|
if (error !== null && typeof error === "object" && typeof error.status === "number" && error.status >= 400 && error.status < 500) {
|
|
752
849
|
stopped = true;
|
|
753
850
|
emitClosed(error);
|
|
@@ -761,9 +858,13 @@ function live(fn) {
|
|
|
761
858
|
if (typeof addEventListener === "function") addEventListener("online", resolve, {
|
|
762
859
|
once: true
|
|
763
860
|
});
|
|
861
|
+
if (invokeSignal) invokeSignal.addEventListener("abort", resolve, {
|
|
862
|
+
once: true
|
|
863
|
+
});
|
|
764
864
|
});
|
|
765
865
|
clearTimeout(timer);
|
|
766
866
|
if (typeof removeEventListener === "function") removeEventListener("online", wake);
|
|
867
|
+
if (invokeSignal) invokeSignal.removeEventListener("abort", wake);
|
|
767
868
|
timer = wake = undefined;
|
|
768
869
|
}
|
|
769
870
|
}
|
|
@@ -776,6 +877,7 @@ function live(fn) {
|
|
|
776
877
|
if (timer !== undefined) clearTimeout(timer);
|
|
777
878
|
if (wake) wake();
|
|
778
879
|
closeIt(value);
|
|
880
|
+
controller.abort();
|
|
779
881
|
emitClosed();
|
|
780
882
|
return Promise.resolve({
|
|
781
883
|
done: true,
|
|
@@ -787,7 +889,9 @@ function live(fn) {
|
|
|
787
889
|
};
|
|
788
890
|
return iterable;
|
|
789
891
|
};
|
|
892
|
+
const wrapped = (...args) => makeIterable(args);
|
|
790
893
|
wrapped[SERVER_FUNCTION_METADATA] = metadata;
|
|
894
|
+
wrapped[SERVER_FUNCTION_INVOKE] = makeIterable;
|
|
791
895
|
wrapped.id = id;
|
|
792
896
|
Object.defineProperty(wrapped, "url", {
|
|
793
897
|
get: () => fn.url,
|
|
@@ -805,10 +909,10 @@ function getServerFunctionInvocation() {
|
|
|
805
909
|
exports.ChunkReader = ChunkReader;
|
|
806
910
|
exports.ERROR_HEADER = ERROR_HEADER;
|
|
807
911
|
exports.FLASH_COOKIE = FLASH_COOKIE;
|
|
808
|
-
exports.FUNCTION_HEADER = FUNCTION_HEADER;
|
|
809
912
|
exports.GET = GET;
|
|
810
913
|
exports.INSTANCE_HEADER = INSTANCE_HEADER;
|
|
811
914
|
exports.REVALIDATE_HEADER = REVALIDATE_HEADER;
|
|
915
|
+
exports.SERVER_FUNCTION_INVOKE = SERVER_FUNCTION_INVOKE;
|
|
812
916
|
exports.SINGLE_FLIGHT_HEADER = SINGLE_FLIGHT_HEADER;
|
|
813
917
|
exports.clearFlashCookie = clearFlashCookie;
|
|
814
918
|
exports.configureServerFunctionsClient = configureServerFunctionsClient;
|
|
@@ -825,10 +929,13 @@ exports.getServerFunctionInvocation = getServerFunctionInvocation;
|
|
|
825
929
|
exports.getServerFunctionMetadata = getServerFunctionMetadata;
|
|
826
930
|
exports.getServerFunctionsCodec = getServerFunctionsCodec;
|
|
827
931
|
exports.hasFlashCookie = hasFlashCookie;
|
|
932
|
+
exports.invoke = invoke;
|
|
828
933
|
exports.isServerFunction = isServerFunction;
|
|
829
934
|
exports.live = live;
|
|
830
935
|
exports.observeServerFunctionCalls = observeServerFunctionCalls;
|
|
936
|
+
exports.parseServerFunctionUrl = parseServerFunctionUrl;
|
|
831
937
|
exports.registerServerReference = registerServerReference;
|
|
832
938
|
exports.serializeString = serializeString;
|
|
939
|
+
exports.serverFunctionUrl = serverFunctionUrl;
|
|
833
940
|
exports.subscribeFlightData = subscribeFlightData;
|
|
834
941
|
exports.withMeta = withMeta;
|