@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.
Files changed (86) hide show
  1. package/dist/dev.cjs +433 -72
  2. package/dist/dev.js +426 -71
  3. package/dist/server.cjs +39 -21
  4. package/dist/server.js +40 -23
  5. package/dist/web.cjs +421 -70
  6. package/dist/web.js +414 -69
  7. package/frames/dist/client.cjs +8 -8
  8. package/frames/dist/client.dev.cjs +8 -8
  9. package/frames/dist/client.dev.js +8 -8
  10. package/frames/dist/client.js +8 -8
  11. package/frames/dist/server.cjs +28 -18
  12. package/frames/dist/server.js +29 -19
  13. package/package.json +20 -22
  14. package/serialization/dist/decode.cjs +3 -3
  15. package/serialization/dist/decode.js +3 -3
  16. package/serialization/dist/serialization.cjs +7 -11
  17. package/serialization/dist/serialization.js +7 -6
  18. package/serialization/types/index.d.ts +69 -157
  19. package/serialization/types/serializer-decode.d.ts +89 -112
  20. package/serialization/types/serializer.d.ts +94 -0
  21. package/serialization/types-cjs/index.d.cts +69 -157
  22. package/serialization/types-cjs/serializer-decode.d.cts +89 -112
  23. package/serialization/types-cjs/serializer.d.cts +94 -0
  24. package/server-functions/dist/client.cjs +126 -19
  25. package/server-functions/dist/client.js +123 -19
  26. package/server-functions/dist/server.cjs +156 -28
  27. package/server-functions/dist/server.dev.cjs +156 -28
  28. package/server-functions/dist/server.dev.js +153 -28
  29. package/server-functions/dist/server.js +153 -28
  30. package/types/client.d.ts +152 -290
  31. package/types/constants.d.ts +18 -0
  32. package/types/cookies.d.ts +31 -75
  33. package/types/frames/frame-client.d.ts +287 -277
  34. package/types/frames/frame-container-plugin.d.ts +71 -0
  35. package/types/frames/frame-sink.d.ts +58 -160
  36. package/types/frames/frame-transport.d.ts +161 -194
  37. package/types/frames/serializer-decode.d.ts +159 -0
  38. package/types/frames/serializer.d.ts +69 -157
  39. package/types/head.d.ts +16 -0
  40. package/types/index.d.ts +1 -65
  41. package/types/index.server.d.ts +125 -0
  42. package/types/jsx.d.ts +5 -13
  43. package/types/patch-driver.d.ts +3 -0
  44. package/types/reconcile.d.ts +1 -0
  45. package/types/render.d.ts +4 -0
  46. package/types/response.d.ts +48 -152
  47. package/types/serializer-decode.d.ts +89 -112
  48. package/types/serializer.d.ts +69 -157
  49. package/types/server-functions/client.d.ts +124 -222
  50. package/types/server-functions/flash.d.ts +10 -30
  51. package/types/server-functions/registry.d.ts +100 -0
  52. package/types/server-functions/rich-args.d.ts +1 -10
  53. package/types/server-functions/server.d.ts +295 -574
  54. package/types/server-functions/shared.d.ts +155 -458
  55. package/types/server-mock.d.ts +2 -2
  56. package/types/server.d.ts +242 -434
  57. package/types-cjs/client.d.cts +152 -290
  58. package/types-cjs/constants.d.cts +18 -0
  59. package/types-cjs/cookies.d.cts +31 -75
  60. package/types-cjs/frames/frame-client.d.cts +287 -277
  61. package/types-cjs/frames/frame-container-plugin.d.cts +71 -0
  62. package/types-cjs/frames/frame-sink.d.cts +58 -160
  63. package/types-cjs/frames/frame-transport.d.cts +161 -194
  64. package/types-cjs/frames/serializer-decode.d.cts +159 -0
  65. package/types-cjs/frames/serializer.d.cts +69 -157
  66. package/types-cjs/head.d.cts +16 -0
  67. package/types-cjs/index.d.cts +1 -65
  68. package/types-cjs/index.server.d.cts +125 -0
  69. package/types-cjs/jsx.d.cts +5 -13
  70. package/types-cjs/patch-driver.d.cts +3 -0
  71. package/types-cjs/reconcile.d.cts +1 -0
  72. package/types-cjs/render.d.cts +4 -0
  73. package/types-cjs/response.d.cts +48 -152
  74. package/types-cjs/serializer-decode.d.cts +89 -112
  75. package/types-cjs/serializer.d.cts +69 -157
  76. package/types-cjs/server-functions/client.d.cts +124 -222
  77. package/types-cjs/server-functions/flash.d.cts +10 -30
  78. package/types-cjs/server-functions/registry.d.cts +100 -0
  79. package/types-cjs/server-functions/rich-args.d.cts +1 -10
  80. package/types-cjs/server-functions/server.d.cts +295 -574
  81. package/types-cjs/server-functions/shared.d.cts +155 -458
  82. package/types-cjs/server-mock.d.cts +2 -2
  83. package/types-cjs/server.d.cts +242 -434
  84. package/LICENSE +0 -21
  85. package/types/core.d.ts +0 -9
  86. 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
- const FUNCTION_HEADER = "X-Server-Function-Id";
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
- if (CALL_OBSERVERS.size === 0) return fetch(base, init);
478
- const request = new Request(new URL(base, globalThis.location?.href || "http://localhost"), init);
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 fetch(request);
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 fn = (...args) => {
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, {}, args, metadata);
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 || `${config.endpoint}?id=${encodeURIComponent(id)}`;
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 wrapped = async (...args) => {
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
- let base = `${config.endpoint}?id=${encodeURIComponent(id)}`;
650
- if (args.length) {
651
- const encoded = isJSONSafe(args) ? JSON.stringify(args) : await serializeArguments(args);
652
- base += `&args=${encodeURIComponent(encoded)}`;
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(base, id, {
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: () => `${config.endpoint}?id=${encodeURIComponent(id)}`,
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 wrapped = (...args) => {
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(...args);
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;