@fragno-dev/forms 0.1.0 → 0.1.2
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/browser/client/react.d.ts +20 -20
- package/dist/browser/client/react.d.ts.map +1 -1
- package/dist/browser/client/react.js +105 -13
- package/dist/browser/client/react.js.map +1 -1
- package/dist/browser/client/solid.d.ts +20 -20
- package/dist/browser/client/solid.d.ts.map +1 -1
- package/dist/browser/client/solid.js +25 -11
- package/dist/browser/client/solid.js.map +1 -1
- package/dist/browser/client/svelte.d.ts +20 -20
- package/dist/browser/client/svelte.d.ts.map +1 -1
- package/dist/browser/client/svelte.js +11 -3
- package/dist/browser/client/svelte.js.map +1 -1
- package/dist/browser/client/vanilla.d.ts +20 -20
- package/dist/browser/client/vanilla.d.ts.map +1 -1
- package/dist/browser/client/vanilla.js +21 -1
- package/dist/browser/client/vanilla.js.map +1 -1
- package/dist/browser/client/vue.d.ts +17 -17
- package/dist/browser/client/vue.d.ts.map +1 -1
- package/dist/browser/client/vue.js +19 -11
- package/dist/browser/client/vue.js.map +1 -1
- package/dist/browser/index.d.ts +417 -107
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/{src-BBaSaf29.js → src-BNcd9ogF.js} +364 -331
- package/dist/browser/src-BNcd9ogF.js.map +1 -0
- package/dist/node/index.d.ts +417 -107
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +83 -90
- package/dist/node/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +28 -48
- package/dist/browser/src-BBaSaf29.js.map +0 -1
|
@@ -15,6 +15,80 @@ function resolveRouteFactories(context, routesOrFactories) {
|
|
|
15
15
|
return routes$1;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region ../fragno/dist/api/internal/path.js
|
|
20
|
+
/**
|
|
21
|
+
* Extract parameter names from a path pattern at runtime.
|
|
22
|
+
* Examples:
|
|
23
|
+
* - "/users/:id" => ["id"]
|
|
24
|
+
* - "/files/**" => ["**"]
|
|
25
|
+
* - "/files/**:rest" => ["rest"]
|
|
26
|
+
*/
|
|
27
|
+
function extractPathParams(pathPattern) {
|
|
28
|
+
const segments = pathPattern.split("/").filter((s) => s.length > 0);
|
|
29
|
+
const names = [];
|
|
30
|
+
for (const segment of segments) {
|
|
31
|
+
if (segment.startsWith(":")) {
|
|
32
|
+
names.push(segment.slice(1));
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (segment === "**") {
|
|
36
|
+
names.push("**");
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (segment.startsWith("**:")) {
|
|
40
|
+
names.push(segment.slice(3));
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return names;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Build a concrete path by replacing placeholders in a path pattern with values.
|
|
48
|
+
*
|
|
49
|
+
* Supports the same placeholder syntax as the matcher:
|
|
50
|
+
* - Named parameter ":name" is URL-encoded as a single segment
|
|
51
|
+
* - Anonymous wildcard "**" inserts the remainder as-is (slashes preserved)
|
|
52
|
+
* - Named wildcard "**:name" inserts the remainder from the named key
|
|
53
|
+
*
|
|
54
|
+
* Examples:
|
|
55
|
+
* - buildPath("/users/:id", { id: "123" }) => "/users/123"
|
|
56
|
+
* - buildPath("/files/**", { "**": "a/b" }) => "/files/a/b"
|
|
57
|
+
* - buildPath("/files/**:rest", { rest: "a/b" }) => "/files/a/b"
|
|
58
|
+
*/
|
|
59
|
+
function buildPath(pathPattern, params) {
|
|
60
|
+
const patternSegments = pathPattern.split("/");
|
|
61
|
+
const builtSegments = [];
|
|
62
|
+
for (const segment of patternSegments) {
|
|
63
|
+
if (segment.length === 0) {
|
|
64
|
+
builtSegments.push("");
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (segment.startsWith(":")) {
|
|
68
|
+
const name = segment.slice(1);
|
|
69
|
+
const value = params[name];
|
|
70
|
+
if (value === void 0) throw new Error(`Missing value for path parameter :${name}`);
|
|
71
|
+
builtSegments.push(encodeURIComponent(value));
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (segment === "**") {
|
|
75
|
+
const value = params["**"];
|
|
76
|
+
if (value === void 0) throw new Error("Missing value for path wildcard **");
|
|
77
|
+
builtSegments.push(value);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (segment.startsWith("**:")) {
|
|
81
|
+
const name = segment.slice(3);
|
|
82
|
+
const value = params[name];
|
|
83
|
+
if (value === void 0) throw new Error(`Missing value for path wildcard **:${name}`);
|
|
84
|
+
builtSegments.push(value);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
builtSegments.push(segment);
|
|
88
|
+
}
|
|
89
|
+
return builtSegments.join("/");
|
|
90
|
+
}
|
|
91
|
+
|
|
18
92
|
//#endregion
|
|
19
93
|
//#region ../fragno/dist/api/internal/route.js
|
|
20
94
|
function getMountRoute(opts) {
|
|
@@ -444,170 +518,6 @@ var RequestOutputContext = class extends OutputContext {
|
|
|
444
518
|
}
|
|
445
519
|
};
|
|
446
520
|
|
|
447
|
-
//#endregion
|
|
448
|
-
//#region ../fragno/dist/api/internal/path.js
|
|
449
|
-
/**
|
|
450
|
-
* Extract parameter names from a path pattern at runtime.
|
|
451
|
-
* Examples:
|
|
452
|
-
* - "/users/:id" => ["id"]
|
|
453
|
-
* - "/files/**" => ["**"]
|
|
454
|
-
* - "/files/**:rest" => ["rest"]
|
|
455
|
-
*/
|
|
456
|
-
function extractPathParams(pathPattern) {
|
|
457
|
-
const segments = pathPattern.split("/").filter((s) => s.length > 0);
|
|
458
|
-
const names = [];
|
|
459
|
-
for (const segment of segments) {
|
|
460
|
-
if (segment.startsWith(":")) {
|
|
461
|
-
names.push(segment.slice(1));
|
|
462
|
-
continue;
|
|
463
|
-
}
|
|
464
|
-
if (segment === "**") {
|
|
465
|
-
names.push("**");
|
|
466
|
-
continue;
|
|
467
|
-
}
|
|
468
|
-
if (segment.startsWith("**:")) {
|
|
469
|
-
names.push(segment.slice(3));
|
|
470
|
-
continue;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
return names;
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Build a concrete path by replacing placeholders in a path pattern with values.
|
|
477
|
-
*
|
|
478
|
-
* Supports the same placeholder syntax as the matcher:
|
|
479
|
-
* - Named parameter ":name" is URL-encoded as a single segment
|
|
480
|
-
* - Anonymous wildcard "**" inserts the remainder as-is (slashes preserved)
|
|
481
|
-
* - Named wildcard "**:name" inserts the remainder from the named key
|
|
482
|
-
*
|
|
483
|
-
* Examples:
|
|
484
|
-
* - buildPath("/users/:id", { id: "123" }) => "/users/123"
|
|
485
|
-
* - buildPath("/files/**", { "**": "a/b" }) => "/files/a/b"
|
|
486
|
-
* - buildPath("/files/**:rest", { rest: "a/b" }) => "/files/a/b"
|
|
487
|
-
*/
|
|
488
|
-
function buildPath(pathPattern, params) {
|
|
489
|
-
const patternSegments = pathPattern.split("/");
|
|
490
|
-
const builtSegments = [];
|
|
491
|
-
for (const segment of patternSegments) {
|
|
492
|
-
if (segment.length === 0) {
|
|
493
|
-
builtSegments.push("");
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
if (segment.startsWith(":")) {
|
|
497
|
-
const name = segment.slice(1);
|
|
498
|
-
const value = params[name];
|
|
499
|
-
if (value === void 0) throw new Error(`Missing value for path parameter :${name}`);
|
|
500
|
-
builtSegments.push(encodeURIComponent(value));
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
if (segment === "**") {
|
|
504
|
-
const value = params["**"];
|
|
505
|
-
if (value === void 0) throw new Error("Missing value for path wildcard **");
|
|
506
|
-
builtSegments.push(value);
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
if (segment.startsWith("**:")) {
|
|
510
|
-
const name = segment.slice(3);
|
|
511
|
-
const value = params[name];
|
|
512
|
-
if (value === void 0) throw new Error(`Missing value for path wildcard **:${name}`);
|
|
513
|
-
builtSegments.push(value);
|
|
514
|
-
continue;
|
|
515
|
-
}
|
|
516
|
-
builtSegments.push(segment);
|
|
517
|
-
}
|
|
518
|
-
return builtSegments.join("/");
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
//#endregion
|
|
522
|
-
//#region ../fragno/dist/client/client-error.js
|
|
523
|
-
/**
|
|
524
|
-
* Base error class for all Fragno client errors.
|
|
525
|
-
*/
|
|
526
|
-
var FragnoClientError = class extends Error {
|
|
527
|
-
#code;
|
|
528
|
-
constructor(message, code, options = {}) {
|
|
529
|
-
super(message, { cause: options.cause });
|
|
530
|
-
this.name = "FragnoClientError";
|
|
531
|
-
this.#code = code;
|
|
532
|
-
}
|
|
533
|
-
get code() {
|
|
534
|
-
return this.#code;
|
|
535
|
-
}
|
|
536
|
-
};
|
|
537
|
-
var FragnoClientFetchError = class extends FragnoClientError {
|
|
538
|
-
constructor(message, code, options = {}) {
|
|
539
|
-
super(message, code, options);
|
|
540
|
-
this.name = "FragnoClientFetchError";
|
|
541
|
-
}
|
|
542
|
-
static fromUnknownFetchError(error) {
|
|
543
|
-
if (!(error instanceof Error)) return new FragnoClientFetchNetworkError("Network request failed", { cause: error });
|
|
544
|
-
if (error.name === "AbortError") return new FragnoClientFetchAbortError("Request was aborted", { cause: error });
|
|
545
|
-
return new FragnoClientFetchNetworkError("Network request failed", { cause: error });
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
/**
|
|
549
|
-
* Error thrown when a network request fails (e.g., no internet connection, DNS failure).
|
|
550
|
-
*/
|
|
551
|
-
var FragnoClientFetchNetworkError = class extends FragnoClientFetchError {
|
|
552
|
-
constructor(message = "Network request failed", options = {}) {
|
|
553
|
-
super(message, "NETWORK_ERROR", options);
|
|
554
|
-
this.name = "FragnoClientFetchNetworkError";
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
/**
|
|
558
|
-
* Error thrown when a request is aborted (e.g., user cancels request, timeout).
|
|
559
|
-
*/
|
|
560
|
-
var FragnoClientFetchAbortError = class extends FragnoClientFetchError {
|
|
561
|
-
constructor(message = "Request was aborted", options = {}) {
|
|
562
|
-
super(message, "ABORT_ERROR", options);
|
|
563
|
-
this.name = "FragnoClientFetchAbortError";
|
|
564
|
-
}
|
|
565
|
-
};
|
|
566
|
-
/**
|
|
567
|
-
* Error thrown when the API result is unexpected, e.g. no json is returned.
|
|
568
|
-
*/
|
|
569
|
-
var FragnoClientUnknownApiError = class extends FragnoClientError {
|
|
570
|
-
#status;
|
|
571
|
-
constructor(message = "Unknown API error", status, options = {}) {
|
|
572
|
-
super(message, "UNKNOWN_API_ERROR", options);
|
|
573
|
-
this.name = "FragnoClientUnknownApiError";
|
|
574
|
-
this.#status = status;
|
|
575
|
-
}
|
|
576
|
-
get status() {
|
|
577
|
-
return this.#status;
|
|
578
|
-
}
|
|
579
|
-
};
|
|
580
|
-
var FragnoClientApiError = class FragnoClientApiError$1 extends FragnoClientError {
|
|
581
|
-
#status;
|
|
582
|
-
constructor({ message, code }, status, options = {}) {
|
|
583
|
-
super(message, code, options);
|
|
584
|
-
this.name = "FragnoClientApiError";
|
|
585
|
-
this.#status = status;
|
|
586
|
-
}
|
|
587
|
-
get status() {
|
|
588
|
-
return this.#status;
|
|
589
|
-
}
|
|
590
|
-
/**
|
|
591
|
-
* The error code returned by the API.
|
|
592
|
-
*
|
|
593
|
-
* The type is `TErrorCode` (the set of known error codes for this route), but may also be a string
|
|
594
|
-
* for forward compatibility with future error codes.
|
|
595
|
-
*/
|
|
596
|
-
get code() {
|
|
597
|
-
return super.code;
|
|
598
|
-
}
|
|
599
|
-
static async fromResponse(response) {
|
|
600
|
-
const unknown = await response.json();
|
|
601
|
-
const status = response.status;
|
|
602
|
-
if (!("message" in unknown || "code" in unknown)) return new FragnoClientUnknownApiError("Unknown API error", status);
|
|
603
|
-
if (!(typeof unknown.message === "string" && typeof unknown.code === "string")) return new FragnoClientUnknownApiError("Unknown API error", status);
|
|
604
|
-
return new FragnoClientApiError$1({
|
|
605
|
-
message: unknown.message,
|
|
606
|
-
code: unknown.code
|
|
607
|
-
}, status);
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
|
-
|
|
611
521
|
//#endregion
|
|
612
522
|
//#region ../fragno/dist/util/content-type.js
|
|
613
523
|
/**
|
|
@@ -656,142 +566,36 @@ function parseContentType(contentType) {
|
|
|
656
566
|
}
|
|
657
567
|
|
|
658
568
|
//#endregion
|
|
659
|
-
//#region ../fragno/dist/
|
|
569
|
+
//#region ../fragno/dist/util/nanostores.js
|
|
660
570
|
/**
|
|
661
|
-
*
|
|
571
|
+
* Normalizes a value that could be a plain value, an Atom, or a Vue Ref to a plain value.
|
|
662
572
|
*/
|
|
663
|
-
function
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
reject(new FragnoClientFetchAbortError("Operation was aborted"));
|
|
667
|
-
};
|
|
668
|
-
if (abortSignal.aborted) abortHandler();
|
|
669
|
-
else abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
670
|
-
});
|
|
573
|
+
function unwrapAtom(value) {
|
|
574
|
+
if (value && typeof value === "object" && "get" in value && typeof value.get === "function") return value.get();
|
|
575
|
+
return value;
|
|
671
576
|
}
|
|
672
577
|
/**
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
* This makes it so that we can wait until the first chunk before updating the store, if we did
|
|
677
|
-
* not do this, `loading` would briefly be false before the first item would be populated in the
|
|
678
|
-
* result.
|
|
679
|
-
*
|
|
680
|
-
* @param response - The fetch Response object containing the NDJSON stream
|
|
681
|
-
* @param store - The fetcher store to update with streaming data
|
|
682
|
-
* @param abortSignal - Optional AbortSignal to cancel the streaming operation
|
|
683
|
-
* @returns A promise that resolves to an object containing the first item and a streaming promise
|
|
578
|
+
* Normalizes an object where values can be plain values, Atoms, or Vue Refs.
|
|
579
|
+
* Returns a new object with all values normalized to plain values.
|
|
684
580
|
*/
|
|
685
|
-
|
|
686
|
-
if (!
|
|
687
|
-
|
|
688
|
-
if (abortSignal?.aborted) throw new FragnoClientFetchAbortError("Operation was aborted");
|
|
689
|
-
const decoder = new TextDecoder();
|
|
690
|
-
const reader = response.body.getReader();
|
|
691
|
-
let buffer = "";
|
|
692
|
-
let firstItem = null;
|
|
693
|
-
const items = [];
|
|
694
|
-
try {
|
|
695
|
-
while (firstItem === null) {
|
|
696
|
-
if (abortSignal?.aborted) {
|
|
697
|
-
reader.releaseLock();
|
|
698
|
-
throw new FragnoClientFetchAbortError("Operation was aborted");
|
|
699
|
-
}
|
|
700
|
-
const { done, value } = await (abortSignal ? Promise.race([reader.read(), createAbortPromise(abortSignal)]) : reader.read());
|
|
701
|
-
if (done) break;
|
|
702
|
-
buffer += decoder.decode(value, { stream: true });
|
|
703
|
-
const lines = buffer.split("\n");
|
|
704
|
-
buffer = lines.pop() || "";
|
|
705
|
-
for (const line of lines) {
|
|
706
|
-
if (!line.trim()) continue;
|
|
707
|
-
try {
|
|
708
|
-
const jsonObject = JSON.parse(line);
|
|
709
|
-
items.push(jsonObject);
|
|
710
|
-
if (firstItem === null) {
|
|
711
|
-
firstItem = jsonObject;
|
|
712
|
-
const streamingPromise = continueStreaming(reader, decoder, buffer, items, store, abortSignal);
|
|
713
|
-
return {
|
|
714
|
-
firstItem,
|
|
715
|
-
streamingPromise
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
} catch (parseError) {
|
|
719
|
-
throw new FragnoClientUnknownApiError("Failed to parse NDJSON line", 500, { cause: parseError });
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
if (firstItem === null) {
|
|
724
|
-
reader.releaseLock();
|
|
725
|
-
throw new FragnoClientUnknownApiError("NDJSON stream contained no valid items", 500);
|
|
726
|
-
}
|
|
727
|
-
reader.releaseLock();
|
|
728
|
-
throw new FragnoClientFetchError("Unexpected end of stream processing", "NO_BODY");
|
|
729
|
-
} catch (error) {
|
|
730
|
-
if (error instanceof FragnoClientError) {
|
|
731
|
-
store?.setError(error);
|
|
732
|
-
throw error;
|
|
733
|
-
} else {
|
|
734
|
-
const clientError = new FragnoClientUnknownApiError("Unknown streaming error", 500, { cause: error });
|
|
735
|
-
store?.setError(clientError);
|
|
736
|
-
throw clientError;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
581
|
+
function unwrapObject(params) {
|
|
582
|
+
if (!params) return;
|
|
583
|
+
return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, unwrapAtom(value)]));
|
|
739
584
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
if (buffer.trim()) {
|
|
751
|
-
const lines$1 = buffer.split("\n");
|
|
752
|
-
for (const line of lines$1) {
|
|
753
|
-
if (!line.trim()) continue;
|
|
754
|
-
try {
|
|
755
|
-
const jsonObject = JSON.parse(line);
|
|
756
|
-
items.push(jsonObject);
|
|
757
|
-
store?.setData([...items]);
|
|
758
|
-
} catch (parseError) {
|
|
759
|
-
throw new FragnoClientUnknownApiError("Failed to parse NDJSON line", 400, { cause: parseError });
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
break;
|
|
764
|
-
}
|
|
765
|
-
buffer += decoder.decode(value, { stream: true });
|
|
766
|
-
const lines = buffer.split("\n");
|
|
767
|
-
buffer = lines.pop() || "";
|
|
768
|
-
for (const line of lines) {
|
|
769
|
-
if (!line.trim()) continue;
|
|
770
|
-
try {
|
|
771
|
-
const jsonObject = JSON.parse(line);
|
|
772
|
-
items.push(jsonObject);
|
|
773
|
-
store?.setData([...items]);
|
|
774
|
-
} catch (parseError) {
|
|
775
|
-
throw new FragnoClientUnknownApiError("Failed to parse NDJSON line", 400, { cause: parseError });
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
} catch (error) {
|
|
780
|
-
if (error instanceof FragnoClientError) store?.setError(error);
|
|
781
|
-
else {
|
|
782
|
-
const clientError = new FragnoClientUnknownApiError("Unknown streaming error", 400, { cause: error });
|
|
783
|
-
store?.setError(clientError);
|
|
784
|
-
throw clientError;
|
|
785
|
-
}
|
|
786
|
-
throw error;
|
|
787
|
-
} finally {
|
|
788
|
-
reader.releaseLock();
|
|
789
|
-
}
|
|
790
|
-
return items;
|
|
585
|
+
function isReadableAtom(value) {
|
|
586
|
+
if (!value) return false;
|
|
587
|
+
if (typeof value !== "object" || value === null) return false;
|
|
588
|
+
if (!("get" in value) || typeof value.get !== "function") return false;
|
|
589
|
+
if (!("lc" in value) || typeof value.lc !== "number") return false;
|
|
590
|
+
if (!("notify" in value) || typeof value.notify !== "function") return false;
|
|
591
|
+
if (!("off" in value) || typeof value.off !== "function") return false;
|
|
592
|
+
if (!("subscribe" in value) || typeof value.subscribe !== "function") return false;
|
|
593
|
+
if (!("value" in value)) return false;
|
|
594
|
+
return true;
|
|
791
595
|
}
|
|
792
596
|
|
|
793
597
|
//#endregion
|
|
794
|
-
//#region ../../node_modules/.pnpm/nanostores@1.
|
|
598
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/task/index.js
|
|
795
599
|
let tasks = 0;
|
|
796
600
|
let resolves = [];
|
|
797
601
|
function startTask() {
|
|
@@ -813,11 +617,11 @@ function task(cb) {
|
|
|
813
617
|
}
|
|
814
618
|
|
|
815
619
|
//#endregion
|
|
816
|
-
//#region ../../node_modules/.pnpm/nanostores@1.
|
|
620
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/clean-stores/index.js
|
|
817
621
|
let clean = Symbol("clean");
|
|
818
622
|
|
|
819
623
|
//#endregion
|
|
820
|
-
//#region ../../node_modules/.pnpm/nanostores@1.
|
|
624
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/atom/index.js
|
|
821
625
|
let listenerQueue = [];
|
|
822
626
|
let lqIndex = 0;
|
|
823
627
|
const QUEUE_ITEMS_PER_LISTENER = 4;
|
|
@@ -829,6 +633,7 @@ const atom = /* @__NO_SIDE_EFFECTS__ */ (initialValue) => {
|
|
|
829
633
|
if (!$atom.lc) $atom.listen(() => {})();
|
|
830
634
|
return $atom.value;
|
|
831
635
|
},
|
|
636
|
+
init: initialValue,
|
|
832
637
|
lc: 0,
|
|
833
638
|
listen(listener) {
|
|
834
639
|
$atom.lc = listeners.push(listener);
|
|
@@ -875,7 +680,7 @@ const atom = /* @__NO_SIDE_EFFECTS__ */ (initialValue) => {
|
|
|
875
680
|
};
|
|
876
681
|
|
|
877
682
|
//#endregion
|
|
878
|
-
//#region ../../node_modules/.pnpm/nanostores@1.
|
|
683
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/lifecycle/index.js
|
|
879
684
|
const START = 0;
|
|
880
685
|
const STOP = 1;
|
|
881
686
|
const MOUNT = 5;
|
|
@@ -970,7 +775,21 @@ let onMount = ($store, initialize) => {
|
|
|
970
775
|
};
|
|
971
776
|
|
|
972
777
|
//#endregion
|
|
973
|
-
//#region ../../node_modules/.pnpm/nanostores@1.
|
|
778
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/warn/index.js
|
|
779
|
+
let warned = {};
|
|
780
|
+
function warn(text) {
|
|
781
|
+
if (!warned[text]) {
|
|
782
|
+
warned[text] = true;
|
|
783
|
+
if (typeof console !== "undefined" && console.warn) {
|
|
784
|
+
console.groupCollapsed("Nano Stores: " + text);
|
|
785
|
+
console.trace("Source of deprecated call");
|
|
786
|
+
console.groupEnd();
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
//#endregion
|
|
792
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/computed/index.js
|
|
974
793
|
let computedStore = (stores$1, cb, batched$1) => {
|
|
975
794
|
if (!Array.isArray(stores$1)) stores$1 = [stores$1];
|
|
976
795
|
let previousArgs;
|
|
@@ -982,10 +801,12 @@ let computedStore = (stores$1, cb, batched$1) => {
|
|
|
982
801
|
if (!previousArgs || args.some((arg, i) => arg !== previousArgs[i])) {
|
|
983
802
|
previousArgs = args;
|
|
984
803
|
let value = cb(...args);
|
|
985
|
-
if (value && value.then && value.t)
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
804
|
+
if (value && value.then && value.t) {
|
|
805
|
+
warn("Use @nanostores/async for async computed. We will remove Promise support in computed() in Nano Stores 2.0");
|
|
806
|
+
value.then((asyncValue) => {
|
|
807
|
+
if (previousArgs === args) $computed.set(asyncValue);
|
|
808
|
+
});
|
|
809
|
+
} else {
|
|
989
810
|
$computed.set(value);
|
|
990
811
|
currentEpoch = epoch;
|
|
991
812
|
}
|
|
@@ -1015,7 +836,7 @@ const computed = /* @__NO_SIDE_EFFECTS__ */ (stores$1, fn) => computedStore(stor
|
|
|
1015
836
|
const batched = /* @__NO_SIDE_EFFECTS__ */ (stores$1, fn) => computedStore(stores$1, fn, true);
|
|
1016
837
|
|
|
1017
838
|
//#endregion
|
|
1018
|
-
//#region ../../node_modules/.pnpm/nanostores@1.
|
|
839
|
+
//#region ../../node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/map/index.js
|
|
1019
840
|
const map = /* @__NO_SIDE_EFFECTS__ */ (initial = {}) => {
|
|
1020
841
|
let $map = atom(initial);
|
|
1021
842
|
$map.setKey = function(key, value) {
|
|
@@ -1052,33 +873,94 @@ function getInitialData(key) {
|
|
|
1052
873
|
}
|
|
1053
874
|
|
|
1054
875
|
//#endregion
|
|
1055
|
-
//#region ../fragno/dist/
|
|
876
|
+
//#region ../fragno/dist/client/client-error.js
|
|
1056
877
|
/**
|
|
1057
|
-
*
|
|
878
|
+
* Base error class for all Fragno client errors.
|
|
1058
879
|
*/
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
}
|
|
880
|
+
var FragnoClientError = class extends Error {
|
|
881
|
+
#code;
|
|
882
|
+
constructor(message, code, options = {}) {
|
|
883
|
+
super(message, { cause: options.cause });
|
|
884
|
+
this.name = "FragnoClientError";
|
|
885
|
+
this.#code = code;
|
|
886
|
+
}
|
|
887
|
+
get code() {
|
|
888
|
+
return this.#code;
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
var FragnoClientFetchError = class extends FragnoClientError {
|
|
892
|
+
constructor(message, code, options = {}) {
|
|
893
|
+
super(message, code, options);
|
|
894
|
+
this.name = "FragnoClientFetchError";
|
|
895
|
+
}
|
|
896
|
+
static fromUnknownFetchError(error) {
|
|
897
|
+
if (!(error instanceof Error)) return new FragnoClientFetchNetworkError("Network request failed", { cause: error });
|
|
898
|
+
if (error.name === "AbortError") return new FragnoClientFetchAbortError("Request was aborted", { cause: error });
|
|
899
|
+
return new FragnoClientFetchNetworkError("Network request failed", { cause: error });
|
|
900
|
+
}
|
|
901
|
+
};
|
|
1063
902
|
/**
|
|
1064
|
-
*
|
|
1065
|
-
* Returns a new object with all values normalized to plain values.
|
|
903
|
+
* Error thrown when a network request fails (e.g., no internet connection, DNS failure).
|
|
1066
904
|
*/
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
}
|
|
905
|
+
var FragnoClientFetchNetworkError = class extends FragnoClientFetchError {
|
|
906
|
+
constructor(message = "Network request failed", options = {}) {
|
|
907
|
+
super(message, "NETWORK_ERROR", options);
|
|
908
|
+
this.name = "FragnoClientFetchNetworkError";
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
/**
|
|
912
|
+
* Error thrown when a request is aborted (e.g., user cancels request, timeout).
|
|
913
|
+
*/
|
|
914
|
+
var FragnoClientFetchAbortError = class extends FragnoClientFetchError {
|
|
915
|
+
constructor(message = "Request was aborted", options = {}) {
|
|
916
|
+
super(message, "ABORT_ERROR", options);
|
|
917
|
+
this.name = "FragnoClientFetchAbortError";
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
/**
|
|
921
|
+
* Error thrown when the API result is unexpected, e.g. no json is returned.
|
|
922
|
+
*/
|
|
923
|
+
var FragnoClientUnknownApiError = class extends FragnoClientError {
|
|
924
|
+
#status;
|
|
925
|
+
constructor(message = "Unknown API error", status, options = {}) {
|
|
926
|
+
super(message, "UNKNOWN_API_ERROR", options);
|
|
927
|
+
this.name = "FragnoClientUnknownApiError";
|
|
928
|
+
this.#status = status;
|
|
929
|
+
}
|
|
930
|
+
get status() {
|
|
931
|
+
return this.#status;
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
var FragnoClientApiError = class FragnoClientApiError$1 extends FragnoClientError {
|
|
935
|
+
#status;
|
|
936
|
+
constructor({ message, code }, status, options = {}) {
|
|
937
|
+
super(message, code, options);
|
|
938
|
+
this.name = "FragnoClientApiError";
|
|
939
|
+
this.#status = status;
|
|
940
|
+
}
|
|
941
|
+
get status() {
|
|
942
|
+
return this.#status;
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* The error code returned by the API.
|
|
946
|
+
*
|
|
947
|
+
* The type is `TErrorCode` (the set of known error codes for this route), but may also be a string
|
|
948
|
+
* for forward compatibility with future error codes.
|
|
949
|
+
*/
|
|
950
|
+
get code() {
|
|
951
|
+
return super.code;
|
|
952
|
+
}
|
|
953
|
+
static async fromResponse(response) {
|
|
954
|
+
const unknown = await response.json();
|
|
955
|
+
const status = response.status;
|
|
956
|
+
if (!("message" in unknown || "code" in unknown)) return new FragnoClientUnknownApiError("Unknown API error", status);
|
|
957
|
+
if (!(typeof unknown.message === "string" && typeof unknown.code === "string")) return new FragnoClientUnknownApiError("Unknown API error", status);
|
|
958
|
+
return new FragnoClientApiError$1({
|
|
959
|
+
message: unknown.message,
|
|
960
|
+
code: unknown.code
|
|
961
|
+
}, status);
|
|
962
|
+
}
|
|
963
|
+
};
|
|
1082
964
|
|
|
1083
965
|
//#endregion
|
|
1084
966
|
//#region ../fragno/dist/client/internal/fetcher-merge.js
|
|
@@ -1114,6 +996,141 @@ function mergeHeaders(author, user) {
|
|
|
1114
996
|
return merged;
|
|
1115
997
|
}
|
|
1116
998
|
|
|
999
|
+
//#endregion
|
|
1000
|
+
//#region ../fragno/dist/client/internal/ndjson-streaming.js
|
|
1001
|
+
/**
|
|
1002
|
+
* Creates a promise that rejects when the abort signal is triggered
|
|
1003
|
+
*/
|
|
1004
|
+
function createAbortPromise(abortSignal) {
|
|
1005
|
+
return new Promise((_, reject) => {
|
|
1006
|
+
const abortHandler = () => {
|
|
1007
|
+
reject(new FragnoClientFetchAbortError("Operation was aborted"));
|
|
1008
|
+
};
|
|
1009
|
+
if (abortSignal.aborted) abortHandler();
|
|
1010
|
+
else abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Handles NDJSON streaming responses by returning the first item from the fetcher
|
|
1015
|
+
* and then continuing to stream updates via the store's mutate method.
|
|
1016
|
+
*
|
|
1017
|
+
* This makes it so that we can wait until the first chunk before updating the store, if we did
|
|
1018
|
+
* not do this, `loading` would briefly be false before the first item would be populated in the
|
|
1019
|
+
* result.
|
|
1020
|
+
*
|
|
1021
|
+
* @param response - The fetch Response object containing the NDJSON stream
|
|
1022
|
+
* @param store - The fetcher store to update with streaming data
|
|
1023
|
+
* @param abortSignal - Optional AbortSignal to cancel the streaming operation
|
|
1024
|
+
* @returns A promise that resolves to an object containing the first item and a streaming promise
|
|
1025
|
+
*/
|
|
1026
|
+
async function handleNdjsonStreamingFirstItem(response, store, options = {}) {
|
|
1027
|
+
if (!response.body) throw new FragnoClientFetchError("Streaming response has no body", "NO_BODY");
|
|
1028
|
+
const { abortSignal } = options;
|
|
1029
|
+
if (abortSignal?.aborted) throw new FragnoClientFetchAbortError("Operation was aborted");
|
|
1030
|
+
const decoder = new TextDecoder();
|
|
1031
|
+
const reader = response.body.getReader();
|
|
1032
|
+
let buffer = "";
|
|
1033
|
+
let firstItem = null;
|
|
1034
|
+
const items = [];
|
|
1035
|
+
try {
|
|
1036
|
+
while (firstItem === null) {
|
|
1037
|
+
if (abortSignal?.aborted) {
|
|
1038
|
+
reader.releaseLock();
|
|
1039
|
+
throw new FragnoClientFetchAbortError("Operation was aborted");
|
|
1040
|
+
}
|
|
1041
|
+
const { done, value } = await (abortSignal ? Promise.race([reader.read(), createAbortPromise(abortSignal)]) : reader.read());
|
|
1042
|
+
if (done) break;
|
|
1043
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1044
|
+
const lines = buffer.split("\n");
|
|
1045
|
+
buffer = lines.pop() || "";
|
|
1046
|
+
for (const line of lines) {
|
|
1047
|
+
if (!line.trim()) continue;
|
|
1048
|
+
try {
|
|
1049
|
+
const jsonObject = JSON.parse(line);
|
|
1050
|
+
items.push(jsonObject);
|
|
1051
|
+
if (firstItem === null) {
|
|
1052
|
+
firstItem = jsonObject;
|
|
1053
|
+
const streamingPromise = continueStreaming(reader, decoder, buffer, items, store, abortSignal);
|
|
1054
|
+
return {
|
|
1055
|
+
firstItem,
|
|
1056
|
+
streamingPromise
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
} catch (parseError) {
|
|
1060
|
+
throw new FragnoClientUnknownApiError("Failed to parse NDJSON line", 500, { cause: parseError });
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
if (firstItem === null) {
|
|
1065
|
+
reader.releaseLock();
|
|
1066
|
+
throw new FragnoClientUnknownApiError("NDJSON stream contained no valid items", 500);
|
|
1067
|
+
}
|
|
1068
|
+
reader.releaseLock();
|
|
1069
|
+
throw new FragnoClientFetchError("Unexpected end of stream processing", "NO_BODY");
|
|
1070
|
+
} catch (error) {
|
|
1071
|
+
if (error instanceof FragnoClientError) {
|
|
1072
|
+
store?.setError(error);
|
|
1073
|
+
throw error;
|
|
1074
|
+
} else {
|
|
1075
|
+
const clientError = new FragnoClientUnknownApiError("Unknown streaming error", 500, { cause: error });
|
|
1076
|
+
store?.setError(clientError);
|
|
1077
|
+
throw clientError;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Continues streaming the remaining items in the background
|
|
1083
|
+
*/
|
|
1084
|
+
async function continueStreaming(reader, decoder, initialBuffer, items, store, abortSignal) {
|
|
1085
|
+
let buffer = initialBuffer;
|
|
1086
|
+
try {
|
|
1087
|
+
while (true) {
|
|
1088
|
+
if (abortSignal?.aborted) throw new FragnoClientFetchAbortError("Operation was aborted");
|
|
1089
|
+
const { done, value } = await (abortSignal ? Promise.race([reader.read(), createAbortPromise(abortSignal)]) : reader.read());
|
|
1090
|
+
if (done) {
|
|
1091
|
+
if (buffer.trim()) {
|
|
1092
|
+
const lines$1 = buffer.split("\n");
|
|
1093
|
+
for (const line of lines$1) {
|
|
1094
|
+
if (!line.trim()) continue;
|
|
1095
|
+
try {
|
|
1096
|
+
const jsonObject = JSON.parse(line);
|
|
1097
|
+
items.push(jsonObject);
|
|
1098
|
+
store?.setData([...items]);
|
|
1099
|
+
} catch (parseError) {
|
|
1100
|
+
throw new FragnoClientUnknownApiError("Failed to parse NDJSON line", 400, { cause: parseError });
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
break;
|
|
1105
|
+
}
|
|
1106
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1107
|
+
const lines = buffer.split("\n");
|
|
1108
|
+
buffer = lines.pop() || "";
|
|
1109
|
+
for (const line of lines) {
|
|
1110
|
+
if (!line.trim()) continue;
|
|
1111
|
+
try {
|
|
1112
|
+
const jsonObject = JSON.parse(line);
|
|
1113
|
+
items.push(jsonObject);
|
|
1114
|
+
store?.setData([...items]);
|
|
1115
|
+
} catch (parseError) {
|
|
1116
|
+
throw new FragnoClientUnknownApiError("Failed to parse NDJSON line", 400, { cause: parseError });
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
if (error instanceof FragnoClientError) store?.setError(error);
|
|
1122
|
+
else {
|
|
1123
|
+
const clientError = new FragnoClientUnknownApiError("Unknown streaming error", 400, { cause: error });
|
|
1124
|
+
store?.setError(clientError);
|
|
1125
|
+
throw clientError;
|
|
1126
|
+
}
|
|
1127
|
+
throw error;
|
|
1128
|
+
} finally {
|
|
1129
|
+
reader.releaseLock();
|
|
1130
|
+
}
|
|
1131
|
+
return items;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1117
1134
|
//#endregion
|
|
1118
1135
|
//#region ../../node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js
|
|
1119
1136
|
let createNanoEvents = () => ({
|
|
@@ -1130,7 +1147,7 @@ let createNanoEvents = () => ({
|
|
|
1130
1147
|
});
|
|
1131
1148
|
|
|
1132
1149
|
//#endregion
|
|
1133
|
-
//#region ../../node_modules/.pnpm/@nanostores+query@0.3.4_nanostores@1.
|
|
1150
|
+
//#region ../../node_modules/.pnpm/@nanostores+query@0.3.4_nanostores@1.2.0/node_modules/@nanostores/query/dist/nanoquery.js
|
|
1134
1151
|
function defaultOnErrorRetry({ retryCount }) {
|
|
1135
1152
|
return ~~((Math.random() + .5) * (1 << (retryCount < 8 ? retryCount : 8))) * 2e3;
|
|
1136
1153
|
}
|
|
@@ -1540,6 +1557,18 @@ function prepareRequestBody(body, contentType) {
|
|
|
1540
1557
|
headers: { "Content-Type": "application/json" }
|
|
1541
1558
|
};
|
|
1542
1559
|
}
|
|
1560
|
+
async function schemaAllowsUndefined(schema) {
|
|
1561
|
+
try {
|
|
1562
|
+
return !(await schema["~standard"].validate(void 0)).issues;
|
|
1563
|
+
} catch {
|
|
1564
|
+
return false;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
async function assertBodyProvided(body, inputSchema, errorMessage) {
|
|
1568
|
+
if (typeof body !== "undefined" || inputSchema === void 0) return;
|
|
1569
|
+
if (await schemaAllowsUndefined(inputSchema)) return;
|
|
1570
|
+
throw new Error(errorMessage);
|
|
1571
|
+
}
|
|
1543
1572
|
/**
|
|
1544
1573
|
* Merge request headers from multiple sources.
|
|
1545
1574
|
* Returns undefined if there are no headers to merge.
|
|
@@ -1650,9 +1679,13 @@ var ClientBuilder = class {
|
|
|
1650
1679
|
get cacheEntries() {
|
|
1651
1680
|
return Object.fromEntries(this.#cache.entries());
|
|
1652
1681
|
}
|
|
1653
|
-
createStore(
|
|
1682
|
+
createStore(input) {
|
|
1683
|
+
if (typeof input === "function") return {
|
|
1684
|
+
factory: input,
|
|
1685
|
+
[STORE_SYMBOL]: true
|
|
1686
|
+
};
|
|
1654
1687
|
return {
|
|
1655
|
-
obj,
|
|
1688
|
+
obj: input,
|
|
1656
1689
|
[STORE_SYMBOL]: true
|
|
1657
1690
|
};
|
|
1658
1691
|
}
|
|
@@ -1685,7 +1718,7 @@ var ClientBuilder = class {
|
|
|
1685
1718
|
}
|
|
1686
1719
|
#getFetcher() {
|
|
1687
1720
|
if (this.#fetcherConfig?.type === "function") return this.#fetcherConfig.fetcher;
|
|
1688
|
-
return fetch;
|
|
1721
|
+
return globalThis.fetch.bind(globalThis);
|
|
1689
1722
|
}
|
|
1690
1723
|
#getFetcherOptions() {
|
|
1691
1724
|
if (this.#fetcherConfig?.type === "options") return this.#fetcherConfig.options;
|
|
@@ -1859,7 +1892,7 @@ var ClientBuilder = class {
|
|
|
1859
1892
|
const mutatorStore = this.#createMutatorStore(async ({ data }) => {
|
|
1860
1893
|
if (typeof window === "undefined") {}
|
|
1861
1894
|
const { body, path, query } = data;
|
|
1862
|
-
|
|
1895
|
+
await assertBodyProvided(body, route.inputSchema, "Body is required.");
|
|
1863
1896
|
const response = await executeMutateQuery({
|
|
1864
1897
|
body,
|
|
1865
1898
|
path,
|
|
@@ -1898,7 +1931,7 @@ var ClientBuilder = class {
|
|
|
1898
1931
|
} });
|
|
1899
1932
|
const mutateQuery = async (data) => {
|
|
1900
1933
|
const { body, path, query } = data;
|
|
1901
|
-
|
|
1934
|
+
await assertBodyProvided(body, route.inputSchema, "Body is required for mutateQuery");
|
|
1902
1935
|
const response = await executeMutateQuery({
|
|
1903
1936
|
body,
|
|
1904
1937
|
path,
|
|
@@ -1958,7 +1991,7 @@ function createClientBuilder(definition, publicConfig, routesOrFactories, author
|
|
|
1958
1991
|
|
|
1959
1992
|
//#endregion
|
|
1960
1993
|
//#region src/definition.ts
|
|
1961
|
-
const formsFragmentDef = defineFragment("forms").extend((x) => x).
|
|
1994
|
+
const formsFragmentDef = defineFragment("forms").extend((x) => x).providesBaseService(() => {}).build();
|
|
1962
1995
|
|
|
1963
1996
|
//#endregion
|
|
1964
1997
|
//#region src/models.ts
|
|
@@ -2121,4 +2154,4 @@ function createFormsClients(fragnoConfig) {
|
|
|
2121
2154
|
|
|
2122
2155
|
//#endregion
|
|
2123
2156
|
export { atom, createFormsClients, createFormsFragment, formsFragmentDef, isGetHook, isMutatorHook, isReadableAtom, isStore, routes };
|
|
2124
|
-
//# sourceMappingURL=src-
|
|
2157
|
+
//# sourceMappingURL=src-BNcd9ogF.js.map
|