@solidjs/web 2.0.0-rc.0 → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1264,7 +1264,7 @@ function renderToStream(code, options = {}) {
1264
1264
  const styles = collectStreamStyles(key, tracking, headStyles);
1265
1265
  const headOps = error ? null : flushHeadFragment(headRegistry, key);
1266
1266
  if (headOps) emitHeadOps(key, headOps);
1267
- sink.fragment(key, value !== undefined ? value : " ", {
1267
+ sink.fragment(key, resolveSSRSelectValues(value !== undefined ? value : " "), {
1268
1268
  styles,
1269
1269
  revealGroup,
1270
1270
  error
@@ -1356,7 +1356,7 @@ function renderToStream(code, options = {}) {
1356
1356
  }
1357
1357
  serializeRootAssets();
1358
1358
  const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
1359
- sink.shell(html, {
1359
+ sink.shell(resolveSSRSelectValues(html), {
1360
1360
  preloads: tracking.emittedAssets,
1361
1361
  inlineStyles: tracking.inlineStyles,
1362
1362
  tasks,
@@ -2152,6 +2152,93 @@ function ssr(t) {
2152
2152
  };
2153
2153
  return result;
2154
2154
  }
2155
+ function decodeSSREntities(s) {
2156
+ return s.indexOf("&") < 0 ? s : s.replace(/&quot;/g, '"').replace(/&lt;/g, "<").replace(/&amp;/g, "&");
2157
+ }
2158
+ const SELECT_VALUE_ATTR = /\svalue="([^"]*)"/;
2159
+ function tagEnd(html, i) {
2160
+ for (let j = i + 1; j < html.length; j++) {
2161
+ const c = html.charCodeAt(j);
2162
+ if (c === 34) {
2163
+ j = html.indexOf('"', j + 1);
2164
+ if (j < 0) return -1;
2165
+ } else if (c === 62) return j;
2166
+ }
2167
+ return -1;
2168
+ }
2169
+ function optionText(html, from) {
2170
+ let t = "";
2171
+ let i = from;
2172
+ for (;;) {
2173
+ const lt = html.indexOf("<", i);
2174
+ if (lt < 0) return t + html.slice(i);
2175
+ t += html.slice(i, lt);
2176
+ if (!html.startsWith("<!--", lt)) return t;
2177
+ const ce = html.indexOf("-->", lt);
2178
+ if (ce < 0) return t;
2179
+ i = ce + 3;
2180
+ }
2181
+ }
2182
+ function tagIs(html, i, name) {
2183
+ if (!html.startsWith(name, i + 1)) return false;
2184
+ const c = html.charCodeAt(i + 1 + name.length);
2185
+ return c === 32 || c === 62 || c === 9 || c === 10 || c === 13;
2186
+ }
2187
+ function resolveSSRSelectValues(html) {
2188
+ if (html.indexOf("<select") < 0) return html;
2189
+ let out = "";
2190
+ let idx = 0;
2191
+ let sel = null;
2192
+ let i = html.indexOf("<");
2193
+ while (i >= 0) {
2194
+ let e;
2195
+ if (html.charCodeAt(i + 1) === 33) {
2196
+ e = html.charCodeAt(i + 2) === 45 ? html.indexOf("-->", i) : html.indexOf(">", i);
2197
+ if (e < 0) break;
2198
+ if (html.charCodeAt(i + 2) === 45) e += 2;
2199
+ } else {
2200
+ e = tagEnd(html, i);
2201
+ if (e < 0) break;
2202
+ if (sel) {
2203
+ if (html.startsWith("</select>", i)) {
2204
+ out += html.slice(idx, sel.strip) + html.slice(sel.stripEnd, sel.body);
2205
+ let seg = sel.body;
2206
+ if (!sel.defaulted) {
2207
+ for (let k = 0; k < sel.marks.length; k++) {
2208
+ out += html.slice(seg, sel.marks[k]) + " selected";
2209
+ seg = sel.marks[k];
2210
+ }
2211
+ }
2212
+ out += html.slice(seg, i);
2213
+ idx = i;
2214
+ sel = null;
2215
+ } else if (tagIs(html, i, "option")) {
2216
+ const attrs = html.slice(i + 7, e);
2217
+ if (/\sselected(?=[\s=]|$)/.test(attrs)) sel.defaulted = true;else {
2218
+ const vm = SELECT_VALUE_ATTR.exec(attrs);
2219
+ const value = vm ? decodeSSREntities(vm[1]) : decodeSSREntities(optionText(html, e + 1)).replace(/\s+/g, " ").trim();
2220
+ if (sel.values.includes(value)) sel.marks.push(e);
2221
+ }
2222
+ }
2223
+ } else if (tagIs(html, i, "select")) {
2224
+ const m = SELECT_VALUE_ATTR.exec(html.slice(i, e + 1));
2225
+ if (m) {
2226
+ const bound = decodeSSREntities(m[1]);
2227
+ sel = {
2228
+ values: /\smultiple(?=[\s>=])/.test(html.slice(i, e + 1)) ? bound.split(",") : [bound],
2229
+ strip: i + m.index,
2230
+ stripEnd: i + m.index + m[0].length,
2231
+ body: e + 1,
2232
+ marks: [],
2233
+ defaulted: false
2234
+ };
2235
+ }
2236
+ }
2237
+ }
2238
+ i = html.indexOf("<", e + 1);
2239
+ }
2240
+ return out + html.slice(idx);
2241
+ }
2155
2242
  function escape(s, attr) {
2156
2243
  const t = typeof s;
2157
2244
  if (t !== "string") {
@@ -2283,7 +2370,9 @@ function renderHeadAssets(emittedAssets, inlineStyles, nonce) {
2283
2370
  function serializeFragmentAssets(key, boundaryModules, context, name = key) {
2284
2371
  const map = boundaryModules.get(key);
2285
2372
  if (!map || !Object.keys(map).length) return;
2286
- context.serialize(name + "_assets", map);
2373
+ context.serialize(name + "_assets", {
2374
+ ...map
2375
+ });
2287
2376
  }
2288
2377
  function propagateBoundaryStyles(childKey, parentKey, tracking) {
2289
2378
  const childStyles = tracking.getBoundaryStyles(childKey);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@solidjs/web",
3
3
  "description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
4
- "version": "2.0.0-rc.0",
4
+ "version": "2.0.0-rc.1",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -378,10 +378,11 @@
378
378
  "seroval-plugins": "~1.5.4"
379
379
  },
380
380
  "peerDependencies": {
381
- "solid-js": "^2.0.0-rc.0"
381
+ "solid-js": "^2.0.0-rc.1"
382
382
  },
383
383
  "devDependencies": {
384
- "solid-js": "2.0.0-rc.0"
384
+ "@codspeed/vitest-plugin": "^5.4.0",
385
+ "solid-js": "2.0.0-rc.1"
385
386
  },
386
387
  "scripts": {
387
388
  "build": "npm-run-all -nl build:clean types:copy-jsx build:js",
@@ -79,12 +79,24 @@ function resolveCodecOptions({
79
79
  function createJSONDeserializer(options) {
80
80
  const refs = new Map();
81
81
  const resolved = resolveCodecOptions(options);
82
- return function deserializeJSONChunk(node) {
82
+ function deserializeJSONChunk(node) {
83
83
  return seroval.fromCrossJSON(node, {
84
84
  refs,
85
85
  ...resolved
86
86
  });
87
+ }
88
+ deserializeJSONChunk.abort = function abort(error) {
89
+ for (const value of refs.values()) {
90
+ if (value === null || typeof value !== "object") continue;
91
+ if (value.__SEROVAL_STREAM__) {
92
+ value.throw(error);
93
+ } else if (typeof value.s === "function" && typeof value.f === "function" && value.p instanceof Promise) {
94
+ value.p.then(undefined, () => {});
95
+ value.f(error);
96
+ }
97
+ }
87
98
  };
99
+ return deserializeJSONChunk;
88
100
  }
89
101
  function createJSONDataTable(options) {
90
102
  const deserialize = createJSONDeserializer(options);
@@ -77,12 +77,24 @@ function resolveCodecOptions({
77
77
  function createJSONDeserializer(options) {
78
78
  const refs = new Map();
79
79
  const resolved = resolveCodecOptions(options);
80
- return function deserializeJSONChunk(node) {
80
+ function deserializeJSONChunk(node) {
81
81
  return fromCrossJSON(node, {
82
82
  refs,
83
83
  ...resolved
84
84
  });
85
+ }
86
+ deserializeJSONChunk.abort = function abort(error) {
87
+ for (const value of refs.values()) {
88
+ if (value === null || typeof value !== "object") continue;
89
+ if (value.__SEROVAL_STREAM__) {
90
+ value.throw(error);
91
+ } else if (typeof value.s === "function" && typeof value.f === "function" && value.p instanceof Promise) {
92
+ value.p.then(undefined, () => {});
93
+ value.f(error);
94
+ }
95
+ }
85
96
  };
97
+ return deserializeJSONChunk;
86
98
  }
87
99
  function createJSONDataTable(options) {
88
100
  const deserialize = createJSONDeserializer(options);
@@ -79,12 +79,24 @@ function resolveCodecOptions({
79
79
  function createJSONDeserializer(options) {
80
80
  const refs = new Map();
81
81
  const resolved = resolveCodecOptions(options);
82
- return function deserializeJSONChunk(node) {
82
+ function deserializeJSONChunk(node) {
83
83
  return seroval.fromCrossJSON(node, {
84
84
  refs,
85
85
  ...resolved
86
86
  });
87
+ }
88
+ deserializeJSONChunk.abort = function abort(error) {
89
+ for (const value of refs.values()) {
90
+ if (value === null || typeof value !== "object") continue;
91
+ if (value.__SEROVAL_STREAM__) {
92
+ value.throw(error);
93
+ } else if (typeof value.s === "function" && typeof value.f === "function" && value.p instanceof Promise) {
94
+ value.p.then(undefined, () => {});
95
+ value.f(error);
96
+ }
97
+ }
87
98
  };
99
+ return deserializeJSONChunk;
88
100
  }
89
101
  function createJSONDataTable(options) {
90
102
  const deserialize = createJSONDeserializer(options);
@@ -78,12 +78,24 @@ function resolveCodecOptions({
78
78
  function createJSONDeserializer(options) {
79
79
  const refs = new Map();
80
80
  const resolved = resolveCodecOptions(options);
81
- return function deserializeJSONChunk(node) {
81
+ function deserializeJSONChunk(node) {
82
82
  return fromCrossJSON(node, {
83
83
  refs,
84
84
  ...resolved
85
85
  });
86
+ }
87
+ deserializeJSONChunk.abort = function abort(error) {
88
+ for (const value of refs.values()) {
89
+ if (value === null || typeof value !== "object") continue;
90
+ if (value.__SEROVAL_STREAM__) {
91
+ value.throw(error);
92
+ } else if (typeof value.s === "function" && typeof value.f === "function" && value.p instanceof Promise) {
93
+ value.p.then(undefined, () => {});
94
+ value.f(error);
95
+ }
96
+ }
86
97
  };
98
+ return deserializeJSONChunk;
87
99
  }
88
100
  function createJSONDataTable(options) {
89
101
  const deserialize = createJSONDeserializer(options);
@@ -18,6 +18,7 @@ function withMeta(fn, meta) {
18
18
  Object.assign(metadata, meta);
19
19
  return fn;
20
20
  }
21
+ const LIVE_SOURCE = Symbol.for("solid.LiveSource");
21
22
  const SERVER_FUNCTION_RPC = Symbol.for("solid.ServerFunctionRPC");
22
23
  function provideServerFunctionRPC(rpc) {
23
24
  globalThis[SERVER_FUNCTION_RPC] || (globalThis[SERVER_FUNCTION_RPC] = rpc);
@@ -138,7 +139,7 @@ const BodyFormat = {
138
139
  Uint8Array: "7",
139
140
  Json: "8"
140
141
  };
141
- const JSON_SAFE_DEPTH_LIMIT = 10000;
142
+ const JSON_SAFE_DEPTH_LIMIT = 4096;
142
143
  const EXIT = {};
143
144
  function isJSONSafe(value) {
144
145
  const stack = [value];
@@ -165,6 +166,7 @@ function isJSONSafe(value) {
165
166
  } else {
166
167
  const proto = Object.getPrototypeOf(v);
167
168
  if (proto !== Object.prototype && proto !== null) return false;
169
+ if (Symbol.asyncIterator in v || Symbol.iterator in v) return false;
168
170
  for (const k in v) stack.push(v[k]);
169
171
  }
170
172
  }
@@ -366,7 +368,7 @@ async function deserializeStream(source, codecOptions) {
366
368
  function interpretChunk(chunk) {
367
369
  return deserializeChunk(JSON.parse(chunk));
368
370
  }
369
- void reader.drain(interpretChunk);
371
+ reader.drain(interpretChunk).then(() => deserializeChunk.abort(new Error("Server function stream ended unexpectedly.")), error => deserializeChunk.abort(error));
370
372
  return interpretChunk(result.value);
371
373
  }
372
374
  return undefined;
@@ -429,7 +431,7 @@ async function createRequest(base, id, instance, options, meta) {
429
431
  [FUNCTION_HEADER]: id,
430
432
  [INSTANCE_HEADER]: instance
431
433
  };
432
- if (getFlightDataConsumer() && (!options.method || options.method.toUpperCase() !== "GET")) {
434
+ if (getFlightDataConsumer() && !options.read && (!options.method || options.method.toUpperCase() !== "GET")) {
433
435
  headers[SINGLE_FLIGHT_HEADER] = "true";
434
436
  }
435
437
  let init = {
@@ -511,6 +513,11 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
511
513
  id,
512
514
  meta
513
515
  }) : undefined;
516
+ const controller = options.signal ? undefined : new AbortController();
517
+ if (controller) options = {
518
+ ...options,
519
+ signal: controller.signal
520
+ };
514
521
  const response = await initializeResponse(base, id, instance, options, args, meta);
515
522
  if (handler) {
516
523
  const handled = handler.handle(response, {
@@ -541,6 +548,20 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
541
548
  if (response.headers.has(ERROR_HEADER)) {
542
549
  throw result;
543
550
  }
551
+ if (controller && result?.[Symbol.asyncIterator]) {
552
+ return {
553
+ [Symbol.asyncIterator]() {
554
+ const it = result[Symbol.asyncIterator]();
555
+ return {
556
+ next: () => it.next(),
557
+ return: value => (controller.abort(), Promise.resolve({
558
+ done: true,
559
+ value
560
+ }))
561
+ };
562
+ }
563
+ };
564
+ }
544
565
  return result;
545
566
  }
546
567
  function createServerReference(id, name, base) {
@@ -609,6 +630,131 @@ function GET(fn) {
609
630
  method: "GET"
610
631
  });
611
632
  }
633
+ function live(fn) {
634
+ if (!isServerFunction(fn)) {
635
+ throw new Error("live expects a server function reference");
636
+ }
637
+ const id = fn.id;
638
+ const metadata = {
639
+ ...getServerFunctionMetadata(fn),
640
+ live: true
641
+ };
642
+ const wrapped = (...args) => {
643
+ const iterable = {
644
+ [LIVE_SOURCE]: true,
645
+ [Symbol.asyncIterator]() {
646
+ let it;
647
+ let connected = false;
648
+ let attempts = 0;
649
+ let stopped = false;
650
+ let ended = false;
651
+ let timer, wake;
652
+ const DONE = {
653
+ done: true,
654
+ value: undefined
655
+ };
656
+ const emit = (state, error) => {
657
+ try {
658
+ iterable.onstatus && iterable.onstatus(state, error);
659
+ } catch {}
660
+ };
661
+ const emitClosed = () => {
662
+ if (ended) return;
663
+ ended = true;
664
+ emit("closed");
665
+ };
666
+ const closeIt = value => {
667
+ const current = it;
668
+ it = undefined;
669
+ if (current) {
670
+ try {
671
+ const r = current.return && current.return(value);
672
+ if (r && typeof r.then === "function") r.then(undefined, () => {});
673
+ } catch {}
674
+ }
675
+ };
676
+ const callOnce = () => {
677
+ if (metadata.method === "GET") return fn(...args);
678
+ const handler = config.responseHandler;
679
+ if (handler && handler.intercept) {
680
+ const hit = handler.intercept({
681
+ id,
682
+ meta: metadata,
683
+ args
684
+ });
685
+ if (hit !== undefined) return hit;
686
+ }
687
+ return fetchServerFunction(fn.url, id, {
688
+ read: true
689
+ }, args, metadata, args);
690
+ };
691
+ const pull = async () => {
692
+ while (!stopped) {
693
+ try {
694
+ if (!it) {
695
+ const result = await callOnce();
696
+ connected = true;
697
+ it = result !== null && typeof result === "object" && result[Symbol.asyncIterator] ? result[Symbol.asyncIterator]() : async function* () {
698
+ yield result;
699
+ }();
700
+ if (stopped) {
701
+ closeIt();
702
+ return DONE;
703
+ }
704
+ emit("connected");
705
+ }
706
+ const r = await it.next();
707
+ if (r.done) {
708
+ emitClosed();
709
+ return DONE;
710
+ }
711
+ if (stopped) return DONE;
712
+ attempts = 0;
713
+ return r;
714
+ } catch (error) {
715
+ if (!connected) throw error;
716
+ it = undefined;
717
+ emit("reconnecting", error);
718
+ await new Promise(resolve => {
719
+ wake = resolve;
720
+ timer = setTimeout(resolve, Math.min(500 * 2 ** attempts++, 10000));
721
+ if (typeof addEventListener === "function") addEventListener("online", resolve, {
722
+ once: true
723
+ });
724
+ });
725
+ clearTimeout(timer);
726
+ if (typeof removeEventListener === "function") removeEventListener("online", wake);
727
+ timer = wake = undefined;
728
+ }
729
+ }
730
+ return DONE;
731
+ };
732
+ return {
733
+ next: () => pull(),
734
+ return(value) {
735
+ stopped = true;
736
+ if (timer !== undefined) clearTimeout(timer);
737
+ if (wake) wake();
738
+ closeIt(value);
739
+ emitClosed();
740
+ return Promise.resolve({
741
+ done: true,
742
+ value
743
+ });
744
+ }
745
+ };
746
+ }
747
+ };
748
+ return iterable;
749
+ };
750
+ wrapped[SERVER_FUNCTION_METADATA] = metadata;
751
+ wrapped.id = id;
752
+ Object.defineProperty(wrapped, "url", {
753
+ get: () => fn.url,
754
+ configurable: true
755
+ });
756
+ return wrapped;
757
+ }
612
758
  function registerServerReference() {
613
759
  throw new Error("registerServerReference must not be called in the client build");
614
760
  }
@@ -640,6 +786,7 @@ exports.getServerFunctionMetadata = getServerFunctionMetadata;
640
786
  exports.getServerFunctionsCodec = getServerFunctionsCodec;
641
787
  exports.hasFlashCookie = hasFlashCookie;
642
788
  exports.isServerFunction = isServerFunction;
789
+ exports.live = live;
643
790
  exports.registerServerReference = registerServerReference;
644
791
  exports.serializeString = serializeString;
645
792
  exports.subscribeFlightData = subscribeFlightData;
@@ -16,6 +16,7 @@ function withMeta(fn, meta) {
16
16
  Object.assign(metadata, meta);
17
17
  return fn;
18
18
  }
19
+ const LIVE_SOURCE = Symbol.for("solid.LiveSource");
19
20
  const SERVER_FUNCTION_RPC = Symbol.for("solid.ServerFunctionRPC");
20
21
  function provideServerFunctionRPC(rpc) {
21
22
  globalThis[SERVER_FUNCTION_RPC] || (globalThis[SERVER_FUNCTION_RPC] = rpc);
@@ -136,7 +137,7 @@ const BodyFormat = {
136
137
  Uint8Array: "7",
137
138
  Json: "8"
138
139
  };
139
- const JSON_SAFE_DEPTH_LIMIT = 10000;
140
+ const JSON_SAFE_DEPTH_LIMIT = 4096;
140
141
  const EXIT = {};
141
142
  function isJSONSafe(value) {
142
143
  const stack = [value];
@@ -163,6 +164,7 @@ function isJSONSafe(value) {
163
164
  } else {
164
165
  const proto = Object.getPrototypeOf(v);
165
166
  if (proto !== Object.prototype && proto !== null) return false;
167
+ if (Symbol.asyncIterator in v || Symbol.iterator in v) return false;
166
168
  for (const k in v) stack.push(v[k]);
167
169
  }
168
170
  }
@@ -364,7 +366,7 @@ async function deserializeStream(source, codecOptions) {
364
366
  function interpretChunk(chunk) {
365
367
  return deserializeChunk(JSON.parse(chunk));
366
368
  }
367
- void reader.drain(interpretChunk);
369
+ reader.drain(interpretChunk).then(() => deserializeChunk.abort(new Error("Server function stream ended unexpectedly.")), error => deserializeChunk.abort(error));
368
370
  return interpretChunk(result.value);
369
371
  }
370
372
  return undefined;
@@ -427,7 +429,7 @@ async function createRequest(base, id, instance, options, meta) {
427
429
  [FUNCTION_HEADER]: id,
428
430
  [INSTANCE_HEADER]: instance
429
431
  };
430
- if (getFlightDataConsumer() && (!options.method || options.method.toUpperCase() !== "GET")) {
432
+ if (getFlightDataConsumer() && !options.read && (!options.method || options.method.toUpperCase() !== "GET")) {
431
433
  headers[SINGLE_FLIGHT_HEADER] = "true";
432
434
  }
433
435
  let init = {
@@ -509,6 +511,11 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
509
511
  id,
510
512
  meta
511
513
  }) : undefined;
514
+ const controller = options.signal ? undefined : new AbortController();
515
+ if (controller) options = {
516
+ ...options,
517
+ signal: controller.signal
518
+ };
512
519
  const response = await initializeResponse(base, id, instance, options, args, meta);
513
520
  if (handler) {
514
521
  const handled = handler.handle(response, {
@@ -539,6 +546,20 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
539
546
  if (response.headers.has(ERROR_HEADER)) {
540
547
  throw result;
541
548
  }
549
+ if (controller && result?.[Symbol.asyncIterator]) {
550
+ return {
551
+ [Symbol.asyncIterator]() {
552
+ const it = result[Symbol.asyncIterator]();
553
+ return {
554
+ next: () => it.next(),
555
+ return: value => (controller.abort(), Promise.resolve({
556
+ done: true,
557
+ value
558
+ }))
559
+ };
560
+ }
561
+ };
562
+ }
542
563
  return result;
543
564
  }
544
565
  function createServerReference(id, name, base) {
@@ -607,6 +628,131 @@ function GET(fn) {
607
628
  method: "GET"
608
629
  });
609
630
  }
631
+ function live(fn) {
632
+ if (!isServerFunction(fn)) {
633
+ throw new Error("live expects a server function reference");
634
+ }
635
+ const id = fn.id;
636
+ const metadata = {
637
+ ...getServerFunctionMetadata(fn),
638
+ live: true
639
+ };
640
+ const wrapped = (...args) => {
641
+ const iterable = {
642
+ [LIVE_SOURCE]: true,
643
+ [Symbol.asyncIterator]() {
644
+ let it;
645
+ let connected = false;
646
+ let attempts = 0;
647
+ let stopped = false;
648
+ let ended = false;
649
+ let timer, wake;
650
+ const DONE = {
651
+ done: true,
652
+ value: undefined
653
+ };
654
+ const emit = (state, error) => {
655
+ try {
656
+ iterable.onstatus && iterable.onstatus(state, error);
657
+ } catch {}
658
+ };
659
+ const emitClosed = () => {
660
+ if (ended) return;
661
+ ended = true;
662
+ emit("closed");
663
+ };
664
+ const closeIt = value => {
665
+ const current = it;
666
+ it = undefined;
667
+ if (current) {
668
+ try {
669
+ const r = current.return && current.return(value);
670
+ if (r && typeof r.then === "function") r.then(undefined, () => {});
671
+ } catch {}
672
+ }
673
+ };
674
+ const callOnce = () => {
675
+ if (metadata.method === "GET") return fn(...args);
676
+ const handler = config.responseHandler;
677
+ if (handler && handler.intercept) {
678
+ const hit = handler.intercept({
679
+ id,
680
+ meta: metadata,
681
+ args
682
+ });
683
+ if (hit !== undefined) return hit;
684
+ }
685
+ return fetchServerFunction(fn.url, id, {
686
+ read: true
687
+ }, args, metadata, args);
688
+ };
689
+ const pull = async () => {
690
+ while (!stopped) {
691
+ try {
692
+ if (!it) {
693
+ const result = await callOnce();
694
+ connected = true;
695
+ it = result !== null && typeof result === "object" && result[Symbol.asyncIterator] ? result[Symbol.asyncIterator]() : async function* () {
696
+ yield result;
697
+ }();
698
+ if (stopped) {
699
+ closeIt();
700
+ return DONE;
701
+ }
702
+ emit("connected");
703
+ }
704
+ const r = await it.next();
705
+ if (r.done) {
706
+ emitClosed();
707
+ return DONE;
708
+ }
709
+ if (stopped) return DONE;
710
+ attempts = 0;
711
+ return r;
712
+ } catch (error) {
713
+ if (!connected) throw error;
714
+ it = undefined;
715
+ emit("reconnecting", error);
716
+ await new Promise(resolve => {
717
+ wake = resolve;
718
+ timer = setTimeout(resolve, Math.min(500 * 2 ** attempts++, 10000));
719
+ if (typeof addEventListener === "function") addEventListener("online", resolve, {
720
+ once: true
721
+ });
722
+ });
723
+ clearTimeout(timer);
724
+ if (typeof removeEventListener === "function") removeEventListener("online", wake);
725
+ timer = wake = undefined;
726
+ }
727
+ }
728
+ return DONE;
729
+ };
730
+ return {
731
+ next: () => pull(),
732
+ return(value) {
733
+ stopped = true;
734
+ if (timer !== undefined) clearTimeout(timer);
735
+ if (wake) wake();
736
+ closeIt(value);
737
+ emitClosed();
738
+ return Promise.resolve({
739
+ done: true,
740
+ value
741
+ });
742
+ }
743
+ };
744
+ }
745
+ };
746
+ return iterable;
747
+ };
748
+ wrapped[SERVER_FUNCTION_METADATA] = metadata;
749
+ wrapped.id = id;
750
+ Object.defineProperty(wrapped, "url", {
751
+ get: () => fn.url,
752
+ configurable: true
753
+ });
754
+ return wrapped;
755
+ }
610
756
  function registerServerReference() {
611
757
  throw new Error("registerServerReference must not be called in the client build");
612
758
  }
@@ -614,4 +760,4 @@ function getServerFunctionInvocation() {
614
760
  return undefined;
615
761
  }
616
762
 
617
- export { ChunkReader, ERROR_HEADER, FLASH_COOKIE, FUNCTION_HEADER, GET, INSTANCE_HEADER, REVALIDATE_HEADER, SINGLE_FLIGHT_HEADER, clearFlashCookie, configureServerFunctionsClient, createChunk, createServerReference, decodeErrorHeaderValue, decodeResponse, decodeResponsePayload, deserializeStream, encodeErrorHeaderValue, frameAddress, getFlightDataConsumer, getServerFunctionInvocation, getServerFunctionMetadata, getServerFunctionsCodec, hasFlashCookie, isServerFunction, registerServerReference, serializeString, subscribeFlightData, withMeta };
763
+ export { ChunkReader, ERROR_HEADER, FLASH_COOKIE, FUNCTION_HEADER, GET, INSTANCE_HEADER, REVALIDATE_HEADER, SINGLE_FLIGHT_HEADER, clearFlashCookie, configureServerFunctionsClient, createChunk, createServerReference, decodeErrorHeaderValue, decodeResponse, decodeResponsePayload, deserializeStream, encodeErrorHeaderValue, frameAddress, getFlightDataConsumer, getServerFunctionInvocation, getServerFunctionMetadata, getServerFunctionsCodec, hasFlashCookie, isServerFunction, live, registerServerReference, serializeString, subscribeFlightData, withMeta };