@fragmentsx/runtime-react 0.2.0-dev-20260922090625 → 0.2.0-dev-20260928114300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/index.d.ts +84 -8
- package/dist/index.es.js +289 -175
- package/dist/index.umd.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -60,8 +60,9 @@ function App() {
|
|
|
60
60
|
не передан, клиент бьётся в `window.location.origin`, что удобно при
|
|
61
61
|
same-origin проксировании `/api` на публичный API площадки.
|
|
62
62
|
|
|
63
|
-
`Area`
|
|
64
|
-
|
|
63
|
+
`Area` разрешает область в non-Suspense режиме; `Suspense` остаётся только
|
|
64
|
+
вокруг загрузки модулей конуса. На сервере область не резолвится, не требует
|
|
65
|
+
подключённого `$area` plugin и вместо области отдаёт `options.fallback`. Под капотом:
|
|
65
66
|
|
|
66
67
|
```
|
|
67
68
|
<Area areaCode> → GET <backendEndpoint>/api/area/<code>/compiled
|
|
@@ -79,10 +80,12 @@ import { FragmentRenderer } from '@fragmentsx/runtime-react';
|
|
|
79
80
|
<FragmentRenderer fragmentId={42} props={{ title: 'Привет' }} />
|
|
80
81
|
```
|
|
81
82
|
|
|
82
|
-
`AreaProps` — `{ areaCode: string; options?: { timeout?, pause?, ssr? } }`.
|
|
83
|
+
`AreaProps` — `{ areaCode: string; options?: { timeout?, pause?, ssr? (зарезервирована), props?, fallback?, onError?, empty? } }`.
|
|
83
84
|
`FragmentRendererProps` — `{ fragmentId: number; props?; globalCssUrl?;
|
|
84
85
|
projectProperties?; onError? }`.
|
|
85
86
|
|
|
87
|
+
`options.fallback` показывает узел, пока область или модули загружаются; `options.empty` — когда контента не будет. `empty` принимает React-узел либо функцию `(reason, retry) => ReactNode`: `reason.kind` бывает `no-variant`, `misconfigured` или `failed`, а `retry` доступен только функциональной форме и намеренно не троттлится. `reason` предназначен для ветвления и диагностики, а не для готового к показу текста: `reason.error` и его код — внутренняя диагностика Fragments, решение об их отображении принимает площадка.
|
|
88
|
+
|
|
86
89
|
## Обработка ошибок
|
|
87
90
|
|
|
88
91
|
Пакет реэкспортирует типизированные ошибки транспорта, чтобы их можно было
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { AreaSourceTransport } from '@fragmentsx/fragments-client';
|
|
1
2
|
import { ComponentType } from 'react';
|
|
2
3
|
import { Context } from 'react';
|
|
3
4
|
import { createFragmentsClient } from '@fragmentsx/fragments-client';
|
|
4
5
|
import { CreateFragmentsClientOptions } from '@fragmentsx/fragments-client';
|
|
6
|
+
import { createSourceCache } from '@fragmentsx/fragments-client';
|
|
5
7
|
import { FC } from 'react';
|
|
6
8
|
import { FragmentsApiVersionError } from '@fragmentsx/fragments-client';
|
|
7
9
|
import { FragmentsAreaError } from '@fragmentsx/fragments-client';
|
|
@@ -10,6 +12,13 @@ import { GraphState } from '@graph-state/core';
|
|
|
10
12
|
import { ReactElement } from 'react';
|
|
11
13
|
import { ReactNode } from 'react';
|
|
12
14
|
import { ResolvedSlotPosition } from '@fragmentsx/fragments-client';
|
|
15
|
+
import { SourceCache } from '@fragmentsx/fragments-client';
|
|
16
|
+
import { SourceCacheEntry } from '@fragmentsx/fragments-client';
|
|
17
|
+
import { SourceCall } from '@fragmentsx/fragments-client';
|
|
18
|
+
import { SourceOrigin } from '@fragmentsx/fragments-client';
|
|
19
|
+
import { SourcePendingEntry } from '@fragmentsx/fragments-client';
|
|
20
|
+
import { SourceReadyEntry } from '@fragmentsx/fragments-client';
|
|
21
|
+
import { SourceRun } from '@fragmentsx/fragments-client';
|
|
13
22
|
|
|
14
23
|
/**
|
|
15
24
|
* Area — публичный компонент для рендеринга compiled fragment в consumer app.
|
|
@@ -21,8 +30,8 @@ export declare const Area: FC<AreaProps>;
|
|
|
21
30
|
|
|
22
31
|
/**
|
|
23
32
|
* Сентинел нерезолвленной области — возвращается вместо чтения `$area.read`,
|
|
24
|
-
* когда на сервере `options.ssr === false`,
|
|
25
|
-
* (
|
|
33
|
+
* когда на сервере `options.ssr === false`, при терминальной ошибке серверного
|
|
34
|
+
* suspense-чтения (D-110-04), либо когда `options.pause === true`.
|
|
26
35
|
*
|
|
27
36
|
* Совместим с `UseAreaResult` по форме (тип возврата хука не расширяется),
|
|
28
37
|
* поэтому правка остаётся minor: потребитель, передающий `rootFragmentId`
|
|
@@ -31,22 +40,38 @@ export declare const Area: FC<AreaProps>;
|
|
|
31
40
|
*/
|
|
32
41
|
export declare const AREA_UNRESOLVED: UseAreaResult;
|
|
33
42
|
|
|
43
|
+
/** ФБ-04: static or contextual replacement content for a terminal Area outcome. */
|
|
44
|
+
export declare type AreaEmpty = ReactNode | ((reason: AreaEmptyReason, retry: () => void) => ReactNode);
|
|
45
|
+
|
|
46
|
+
/** D-110-01: terminal area resolution outcome exposed to the consumer fallback. */
|
|
47
|
+
export declare type AreaEmptyReason = {
|
|
48
|
+
kind: AreaEmptyReasonKind;
|
|
49
|
+
code?: string;
|
|
50
|
+
error: Error;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** D-110-01/D-110-02: semantic category for a terminal area resolution outcome. */
|
|
54
|
+
export declare type AreaEmptyReasonKind = "no-variant" | "misconfigured" | "failed";
|
|
55
|
+
|
|
34
56
|
/**
|
|
35
57
|
* Props для Area компонента (D-09, сокращён Phase 73 B-13; расширен quick 260830-rvp):
|
|
36
58
|
* - areaCode — строковый код области (Area.code в backend schema)
|
|
37
59
|
* - options.pause — пропустить рендер (conditional skip per legacy contract)
|
|
38
60
|
* - options.timeout — network timeout для $area.resolve fetch
|
|
39
|
-
* - options.ssr —
|
|
40
|
-
*
|
|
41
|
-
*
|
|
61
|
+
* - options.ssr — зарезервирована ради совместимости сигнатуры и не влияет
|
|
62
|
+
* на resolve: Area всегда отключает серверный resolve (ФБ-06). Рабочая
|
|
63
|
+
* опция сохранила бы известную SSR-мину, а тихое игнорирование стало бы
|
|
64
|
+
* ловушкой для площадки; удаление требует отдельного решения.
|
|
42
65
|
* - options.props (INT-03) — объект мержится поверх серверных props (ключи
|
|
43
66
|
* потребителя выигрывают), функция вызывается с серверными props и её
|
|
44
67
|
* результат уходит в артефакт целиком. Обе формы поддержаны намеренно —
|
|
45
68
|
* паритет с legacy render-react, с которого мигрирует потребитель.
|
|
46
69
|
* - options.fallback (INT-04) — узел, видимый до разрешения области; default
|
|
47
|
-
* `null` (прежнее поведение)
|
|
48
|
-
* - options.
|
|
49
|
-
*
|
|
70
|
+
* `null` (прежнее поведение); в отличие от `empty`, это только загрузка.
|
|
71
|
+
* - options.empty (ФБ-01/ФБ-03/ФБ-04) — узел либо функция для терминального
|
|
72
|
+
* отсутствия контента; без него область, как и прежде, остаётся пустой.
|
|
73
|
+
* - options.onError (INT-04, D-110-06) — вызывается при терминальном resolve
|
|
74
|
+
* либо броске внутри поддерева.
|
|
50
75
|
*/
|
|
51
76
|
export declare interface AreaProps {
|
|
52
77
|
areaCode: string;
|
|
@@ -56,6 +81,7 @@ export declare interface AreaProps {
|
|
|
56
81
|
ssr?: boolean;
|
|
57
82
|
props?: Record<string, unknown> | ((serverProps: Record<string, unknown>) => Record<string, unknown>);
|
|
58
83
|
fallback?: ReactNode;
|
|
84
|
+
empty?: AreaEmpty;
|
|
59
85
|
onError?: (error: Error) => void;
|
|
60
86
|
};
|
|
61
87
|
}
|
|
@@ -206,6 +232,8 @@ export declare type ConsumerPropsFromSchema<S extends Record<string, SchemaField
|
|
|
206
232
|
*/
|
|
207
233
|
export declare function createBrowserClient(opts: BrowserClientOptions): ReturnType<typeof createFragmentsClient>;
|
|
208
234
|
|
|
235
|
+
export { createSourceCache }
|
|
236
|
+
|
|
209
237
|
/**
|
|
210
238
|
* Дефолтное значение, когда Provider не установлен (потребитель вне
|
|
211
239
|
* `FragmentRenderer`, например изолированный юнит-тест компонента).
|
|
@@ -315,6 +343,9 @@ export declare interface FragmentRendererProps {
|
|
|
315
343
|
* правки (дырка рисует пустоту, как и без пропа).
|
|
316
344
|
*/
|
|
317
345
|
slots?: Record<string, ResolvedSlotPosition>;
|
|
346
|
+
sources?: Record<string, AreaSourceTransport>;
|
|
347
|
+
/** Превью в песочнице не может и не должно ходить к источнику (D-111-22) — `offline` ставит SourceNetworkContext на всё поддерево. */
|
|
348
|
+
sourceNetwork?: SourceNetworkMode;
|
|
318
349
|
onError?: (error: Error) => void;
|
|
319
350
|
}
|
|
320
351
|
|
|
@@ -490,6 +521,22 @@ declare type ObjectFieldType<F extends SchemaFieldDescriptor, D extends number>
|
|
|
490
521
|
fields: infer Fields;
|
|
491
522
|
} ? Fields extends Record<string, SchemaFieldDescriptor> ? keyof Fields extends never ? {} : D extends 0 ? ValueOfVariableType<"Object"> : PropsShape<Fields, false, PrevDepth<D>> : {} : {};
|
|
492
523
|
|
|
524
|
+
declare type Operation<S extends keyof SourceMap & string, O extends keyof SourceMap[S] & string> = SourceMap[S][O] extends {
|
|
525
|
+
params: infer P;
|
|
526
|
+
response: infer R;
|
|
527
|
+
} ? {
|
|
528
|
+
params: P;
|
|
529
|
+
response: R;
|
|
530
|
+
} : never;
|
|
531
|
+
|
|
532
|
+
declare type Options<S extends keyof SourceMap & string, O extends keyof SourceMap[S] & string> = Operation<S, O>["params"] extends infer P ? ({} extends P ? {
|
|
533
|
+
target: O;
|
|
534
|
+
params?: P;
|
|
535
|
+
} : {
|
|
536
|
+
target: O;
|
|
537
|
+
params: P;
|
|
538
|
+
}) : never;
|
|
539
|
+
|
|
493
540
|
declare type PrevDepth<D extends number> = D extends 0 ? never : DepthCountdown[D];
|
|
494
541
|
|
|
495
542
|
/**
|
|
@@ -598,6 +645,25 @@ declare type Simplify<T> = {
|
|
|
598
645
|
[K in keyof T]: T[K];
|
|
599
646
|
} & {};
|
|
600
647
|
|
|
648
|
+
export { SourceCache }
|
|
649
|
+
|
|
650
|
+
export { SourceCacheEntry }
|
|
651
|
+
|
|
652
|
+
export { SourceCall }
|
|
653
|
+
|
|
654
|
+
export declare interface SourceMap {
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export declare type SourceNetworkMode = "live" | "offline";
|
|
658
|
+
|
|
659
|
+
export { SourceOrigin }
|
|
660
|
+
|
|
661
|
+
export { SourcePendingEntry }
|
|
662
|
+
|
|
663
|
+
export { SourceReadyEntry }
|
|
664
|
+
|
|
665
|
+
export { SourceRun }
|
|
666
|
+
|
|
601
667
|
/**
|
|
602
668
|
* Ref-counted `<link rel="stylesheet">` injector для compiled fragment CSS delivery (Req #11).
|
|
603
669
|
*
|
|
@@ -707,6 +773,7 @@ export declare interface UseAreaResult {
|
|
|
707
773
|
* (`Area`/`FragmentRenderer`) не делает optional-проверку.
|
|
708
774
|
*/
|
|
709
775
|
slots: Record<string, ResolvedSlotPosition>;
|
|
776
|
+
sources: Record<string, AreaSourceTransport>;
|
|
710
777
|
}
|
|
711
778
|
|
|
712
779
|
/**
|
|
@@ -772,6 +839,15 @@ export declare function useFragmentStylesheet(href: string, key: string): void;
|
|
|
772
839
|
|
|
773
840
|
export declare function useProjectProperty<K extends keyof ProjectProperties>(name: K): ProjectProperties[K];
|
|
774
841
|
|
|
842
|
+
export declare type UseSource = <S extends keyof SourceMap & string, O extends keyof SourceMap[S] & string>(source: S, options: Options<S, O>) => UseSourceResult<Operation<S, O>["response"]>;
|
|
843
|
+
|
|
844
|
+
export declare const useSource: UseSource;
|
|
845
|
+
|
|
846
|
+
export declare type UseSourceResult<T> = {
|
|
847
|
+
data: T | undefined;
|
|
848
|
+
loading: boolean;
|
|
849
|
+
};
|
|
850
|
+
|
|
775
851
|
/** Носитель типа поля `Node` — читает `value`-проекцию третьей таблицы `NODE_TYPE_TO_TS` (D-97-03: три таблицы, три домена, слияние с `VARIABLE_TYPE_TO_TS` запрещено). */
|
|
776
852
|
declare type ValueOfNodeType = (typeof NODE_TYPE_TO_TS)[typeof NODE_SCHEMA_TYPE]["value"];
|
|
777
853
|
|
package/dist/index.es.js
CHANGED
|
@@ -1,45 +1,49 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { jsx as d, jsxs as te, Fragment as ne } from "react/jsx-runtime";
|
|
2
|
+
import * as ae from "react";
|
|
3
|
+
import { createContext as A, useContext as v, useMemo as N, useState as w, useEffect as y, useLayoutEffect as se, version as ue, Component as ce, Suspense as K, createElement as le, useCallback as _, useRef as H, useReducer as oe } from "react";
|
|
4
|
+
import { FragmentsAreaError as de, toScopeClassName as ie, AREA_GLOBAL_CSS_KEY as fe, resolveStylesHref as me, fragmentCssKey as he, createSourceCache as Ee, sourceCallKey as j, sourceTransportKey as ve, resolveSourceRequest as ge, runSourceFetch as ye, createFragmentsClient as Se } from "@fragmentsx/fragments-client";
|
|
5
|
+
import { FragmentsApiVersionError as Qe, FragmentsAreaError as We, FragmentsLoadError as Xe, createSourceCache as Ze } from "@fragmentsx/fragments-client";
|
|
6
|
+
const k = A(
|
|
6
7
|
null
|
|
7
8
|
);
|
|
8
|
-
|
|
9
|
-
function
|
|
10
|
-
return /* @__PURE__ */
|
|
9
|
+
k.displayName = "FragmentsClientContext";
|
|
10
|
+
function Ae(r) {
|
|
11
|
+
return /* @__PURE__ */ d(k.Provider, { value: r.value, children: r.children });
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
function ke() {
|
|
14
|
+
return v(k);
|
|
15
|
+
}
|
|
16
|
+
const z = A(null);
|
|
17
|
+
z.displayName = "InstanceIdContext";
|
|
18
|
+
const F = A(
|
|
15
19
|
null
|
|
16
20
|
);
|
|
17
|
-
|
|
18
|
-
function
|
|
21
|
+
F.displayName = "ModulesMapContext";
|
|
22
|
+
function Ce({
|
|
19
23
|
value: r,
|
|
20
24
|
children: e
|
|
21
25
|
}) {
|
|
22
|
-
return /* @__PURE__ */
|
|
26
|
+
return /* @__PURE__ */ d(F.Provider, { value: r, children: e });
|
|
23
27
|
}
|
|
24
|
-
function
|
|
25
|
-
const r =
|
|
26
|
-
return
|
|
28
|
+
function Ue() {
|
|
29
|
+
const r = v(k);
|
|
30
|
+
return N(
|
|
27
31
|
() => ({
|
|
28
32
|
reachGoal: (e) => {
|
|
29
|
-
var
|
|
30
|
-
(
|
|
33
|
+
var t, n;
|
|
34
|
+
(n = (t = r == null ? void 0 : r.$metrics) == null ? void 0 : t.reachGoal) == null || n.call(t, e);
|
|
31
35
|
}
|
|
32
36
|
}),
|
|
33
37
|
[r]
|
|
34
38
|
);
|
|
35
39
|
}
|
|
36
|
-
function
|
|
37
|
-
const e =
|
|
40
|
+
function Pe(r) {
|
|
41
|
+
const e = v(F);
|
|
38
42
|
if (!e)
|
|
39
43
|
throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");
|
|
40
44
|
return e.read(r);
|
|
41
45
|
}
|
|
42
|
-
const
|
|
46
|
+
const $ = typeof window < "u", L = Object.freeze({
|
|
43
47
|
rootFragmentId: 0,
|
|
44
48
|
variantId: null,
|
|
45
49
|
props: {},
|
|
@@ -49,82 +53,103 @@ const J = typeof window < "u", x = Object.freeze({
|
|
|
49
53
|
// обёртка рендера (задача 3) остаётся без атрибута class на этом сентинеле.
|
|
50
54
|
fragments: [],
|
|
51
55
|
// Phase 106: пустой словарь слотов — сентинел не разворачивает ни одной ссылки.
|
|
52
|
-
slots: {}
|
|
56
|
+
slots: {},
|
|
57
|
+
sources: {}
|
|
53
58
|
});
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
if (!
|
|
57
|
-
throw new Error("[useArea] No FragmentsClientProvider in tree");
|
|
58
|
-
const t = n.$area;
|
|
59
|
-
if (!(t != null && t.read))
|
|
59
|
+
function R(r) {
|
|
60
|
+
const e = r.$area;
|
|
61
|
+
if (!(e != null && e.read))
|
|
60
62
|
throw new Error("[useArea] $area plugin not mounted");
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
return e;
|
|
64
|
+
}
|
|
65
|
+
function Ne(r, e) {
|
|
66
|
+
const t = v(k);
|
|
67
|
+
if (!t)
|
|
68
|
+
throw new Error("[useArea] No FragmentsClientProvider in tree");
|
|
69
|
+
const n = (e == null ? void 0 : e.suspense) ?? !0, s = (e == null ? void 0 : e.pause) === !0 || !$ && (e == null ? void 0 : e.ssr) === !1, a = (e == null ? void 0 : e.timeout) != null ? { timeout: e.timeout } : void 0, [, i] = w(0);
|
|
70
|
+
if (y(() => {
|
|
71
|
+
if (n || s) return;
|
|
72
|
+
const l = R(t);
|
|
73
|
+
let u = !0;
|
|
74
|
+
return Promise.resolve(l.resolve(r, a)).catch(() => {
|
|
66
75
|
}).finally(() => {
|
|
67
|
-
|
|
76
|
+
u && i((E) => E + 1);
|
|
68
77
|
}), () => {
|
|
69
|
-
|
|
78
|
+
u = !1;
|
|
70
79
|
};
|
|
71
|
-
}, [r,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
}, [r, n, e == null ? void 0 : e.pause, e == null ? void 0 : e.timeout, e == null ? void 0 : e.ssr]), n) {
|
|
81
|
+
if (s)
|
|
82
|
+
return L;
|
|
83
|
+
const l = R(t);
|
|
84
|
+
if (l.has(r) || Promise.resolve(l.resolve(r, a)).catch(() => {
|
|
85
|
+
}), !$)
|
|
86
|
+
try {
|
|
87
|
+
return l.read(r);
|
|
88
|
+
} catch (u) {
|
|
89
|
+
if (u != null && typeof u.then == "function")
|
|
90
|
+
throw u;
|
|
91
|
+
return process.env.NODE_ENV !== "production" && console.error(
|
|
92
|
+
`[useArea] Area ${r} remained unresolved on the server because its cache reached a terminal state`,
|
|
93
|
+
u
|
|
94
|
+
), L;
|
|
95
|
+
}
|
|
96
|
+
return l.read(r);
|
|
97
|
+
}
|
|
98
|
+
if (s)
|
|
75
99
|
return { status: "idle", data: null, error: null };
|
|
76
|
-
|
|
100
|
+
const c = R(t);
|
|
101
|
+
if (c.has(r))
|
|
77
102
|
try {
|
|
78
|
-
return { status: "ready", data:
|
|
79
|
-
} catch (
|
|
103
|
+
return { status: "ready", data: c.read(r), error: null };
|
|
104
|
+
} catch (l) {
|
|
80
105
|
return {
|
|
81
106
|
status: "not-found",
|
|
82
107
|
data: null,
|
|
83
|
-
error:
|
|
108
|
+
error: l instanceof Error ? l : new Error(String(l))
|
|
84
109
|
};
|
|
85
110
|
}
|
|
86
|
-
return Promise.resolve(
|
|
111
|
+
return Promise.resolve(c.resolve(r, a)).catch(() => {
|
|
87
112
|
}), { status: "loading", data: null, error: null };
|
|
88
113
|
}
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
91
|
-
const
|
|
114
|
+
const G = typeof window < "u", we = 3e3, P = /* @__PURE__ */ new Map(), Y = (r, e) => {
|
|
115
|
+
if (!G) {
|
|
116
|
+
const h = () => {
|
|
92
117
|
};
|
|
93
|
-
return
|
|
118
|
+
return h.loaded = Promise.resolve(), h;
|
|
94
119
|
}
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
120
|
+
const t = P.get(e);
|
|
121
|
+
if (t) {
|
|
122
|
+
t.refCount += 1;
|
|
123
|
+
const h = () => {
|
|
124
|
+
t.refCount -= 1, t.refCount === 0 && (t.clearReadyTimer(), t.linkEl.remove(), P.delete(e));
|
|
100
125
|
};
|
|
101
|
-
return
|
|
126
|
+
return h.loaded = t.loaded, h;
|
|
102
127
|
}
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
let
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
}),
|
|
109
|
-
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
128
|
+
const n = document.createElement("link");
|
|
129
|
+
n.rel = "stylesheet", n.href = r, n.setAttribute("data-fragment-key", e);
|
|
130
|
+
let s;
|
|
131
|
+
const a = new Promise((h) => {
|
|
132
|
+
s = h;
|
|
133
|
+
}), i = () => {
|
|
134
|
+
l(), s();
|
|
135
|
+
}, c = setTimeout(i, we), l = () => clearTimeout(c);
|
|
136
|
+
n.addEventListener("load", i), n.addEventListener("error", i), document.head.appendChild(n);
|
|
137
|
+
const u = { refCount: 1, linkEl: n, loaded: a, clearReadyTimer: l };
|
|
138
|
+
P.set(e, u);
|
|
139
|
+
const E = () => {
|
|
140
|
+
u.refCount -= 1, u.refCount === 0 && (u.clearReadyTimer(), u.linkEl.remove(), P.delete(e));
|
|
116
141
|
};
|
|
117
|
-
return
|
|
118
|
-
},
|
|
119
|
-
function
|
|
120
|
-
|
|
142
|
+
return E.loaded = a, E;
|
|
143
|
+
}, Fe = G ? se : y;
|
|
144
|
+
function Te(r, e) {
|
|
145
|
+
Fe(() => Y(r, e), [r, e]);
|
|
121
146
|
}
|
|
122
|
-
const
|
|
123
|
-
function
|
|
147
|
+
const Re = parseInt(ue.split(".")[0], 10), _e = Re >= 19;
|
|
148
|
+
function D({
|
|
124
149
|
href: r,
|
|
125
150
|
fragmentKey: e
|
|
126
151
|
}) {
|
|
127
|
-
return
|
|
152
|
+
return _e ? /* @__PURE__ */ d(
|
|
128
153
|
"link",
|
|
129
154
|
{
|
|
130
155
|
rel: "stylesheet",
|
|
@@ -132,148 +157,237 @@ function P({
|
|
|
132
157
|
precedence: "default",
|
|
133
158
|
"data-fragment-key": e
|
|
134
159
|
}
|
|
135
|
-
) : (
|
|
160
|
+
) : (Te(r, e), null);
|
|
161
|
+
}
|
|
162
|
+
function pe(r) {
|
|
163
|
+
}
|
|
164
|
+
const J = {}, x = A(null);
|
|
165
|
+
x.displayName = "ProjectPropertiesContext";
|
|
166
|
+
const q = Object.freeze({}), O = A(q);
|
|
167
|
+
O.displayName = "SourceTransportsContext";
|
|
168
|
+
const b = A("live");
|
|
169
|
+
b.displayName = "SourceNetworkContext";
|
|
170
|
+
function V(r) {
|
|
171
|
+
const e = r instanceof Error ? r : new Error(String(r));
|
|
172
|
+
if (!(e instanceof de))
|
|
173
|
+
return { kind: "failed", error: e };
|
|
174
|
+
const { code: t } = e;
|
|
175
|
+
return t === "NO_ACTIVE_VARIANT" ? { kind: "no-variant", code: t, error: e } : t === "AREA_NOT_FOUND" || t === "NO_PUBLISHED_SNAPSHOT" || t === "NESTED_SNAPSHOT_MISSING" ? { kind: "misconfigured", code: t, error: e } : { kind: "failed", code: t, error: e };
|
|
136
176
|
}
|
|
137
|
-
function
|
|
177
|
+
function Q(r, e, t) {
|
|
178
|
+
return typeof r == "function" ? r(e, t) : r ?? null;
|
|
138
179
|
}
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
180
|
+
const xe = () => {
|
|
181
|
+
};
|
|
182
|
+
function U(r) {
|
|
183
|
+
return r instanceof Error ? r : new Error(String(r));
|
|
184
|
+
}
|
|
185
|
+
class W extends ce {
|
|
142
186
|
constructor() {
|
|
143
|
-
super(...arguments), this.state = { hasError: !1 };
|
|
187
|
+
super(...arguments), this.state = { hasError: !1, error: null };
|
|
144
188
|
}
|
|
145
|
-
static getDerivedStateFromError() {
|
|
146
|
-
return { hasError: !0 };
|
|
189
|
+
static getDerivedStateFromError(e) {
|
|
190
|
+
return { hasError: !0, error: U(e) };
|
|
147
191
|
}
|
|
148
|
-
componentDidCatch(e,
|
|
149
|
-
var
|
|
150
|
-
|
|
192
|
+
componentDidCatch(e, t) {
|
|
193
|
+
var s, a;
|
|
194
|
+
const n = U(e);
|
|
195
|
+
process.env.NODE_ENV !== "production" && console.error("[fragments] Area error:", n, t.componentStack), (a = (s = this.props).onError) == null || a.call(s, n);
|
|
151
196
|
}
|
|
152
197
|
render() {
|
|
153
|
-
|
|
198
|
+
if (this.state.hasError) {
|
|
199
|
+
const e = { kind: "failed", error: this.state.error ?? new Error("Unknown Area error") };
|
|
200
|
+
try {
|
|
201
|
+
return Q(this.props.empty, e, this.props.retry ?? xe);
|
|
202
|
+
} catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return this.props.children;
|
|
154
207
|
}
|
|
155
208
|
}
|
|
156
|
-
function
|
|
209
|
+
function X(r, e) {
|
|
157
210
|
if (!r) return {};
|
|
158
|
-
const
|
|
159
|
-
for (const
|
|
160
|
-
n
|
|
161
|
-
return
|
|
211
|
+
const t = {};
|
|
212
|
+
for (const n of Object.keys(r))
|
|
213
|
+
t[n] = Oe(r[n], e);
|
|
214
|
+
return t;
|
|
162
215
|
}
|
|
163
|
-
function
|
|
164
|
-
return Array.isArray(r) ? r.map((
|
|
216
|
+
function Oe(r, e) {
|
|
217
|
+
return Array.isArray(r) ? r.map((t, n) => t === null ? null : p(t, e, n)) : p(r, e);
|
|
165
218
|
}
|
|
166
|
-
function
|
|
167
|
-
let
|
|
219
|
+
function p(r, e, t) {
|
|
220
|
+
let n;
|
|
168
221
|
try {
|
|
169
|
-
|
|
170
|
-
} catch (
|
|
171
|
-
if (
|
|
172
|
-
throw
|
|
173
|
-
return console.warn(`[FragmentRenderer] Slot fragment ${r.fragmentId} failed to load — rendering empty hole`,
|
|
222
|
+
n = e(r.fragmentId);
|
|
223
|
+
} catch (a) {
|
|
224
|
+
if (a != null && typeof a.then == "function")
|
|
225
|
+
throw a;
|
|
226
|
+
return console.warn(`[FragmentRenderer] Slot fragment ${r.fragmentId} failed to load — rendering empty hole`, a), null;
|
|
174
227
|
}
|
|
175
|
-
const
|
|
176
|
-
return
|
|
228
|
+
const s = X(r.slots, e);
|
|
229
|
+
return le(n, { key: t, ...r.props, ...s });
|
|
177
230
|
}
|
|
178
|
-
const
|
|
231
|
+
const Z = ({
|
|
179
232
|
fragmentId: r,
|
|
180
233
|
props: e,
|
|
181
|
-
globalCssUrl:
|
|
182
|
-
projectProperties:
|
|
183
|
-
fragments:
|
|
184
|
-
slots:
|
|
234
|
+
globalCssUrl: t = null,
|
|
235
|
+
projectProperties: n = J,
|
|
236
|
+
fragments: s = [r],
|
|
237
|
+
slots: a,
|
|
238
|
+
sources: i = q,
|
|
239
|
+
sourceNetwork: c = "live"
|
|
185
240
|
}) => {
|
|
186
|
-
const
|
|
187
|
-
if (!
|
|
241
|
+
const l = Pe(r), u = v(F);
|
|
242
|
+
if (!u)
|
|
188
243
|
throw new Error("[FragmentRendererInner] No ModulesMapProvider in tree");
|
|
189
|
-
const
|
|
190
|
-
return /* @__PURE__ */
|
|
191
|
-
|
|
192
|
-
|
|
244
|
+
const E = X(a, u.read), h = { ...e ?? {}, ...E }, o = s.length > 0 ? s.map(ie).join(" ") : void 0;
|
|
245
|
+
return /* @__PURE__ */ te(ne, { children: [
|
|
246
|
+
t != null && /* @__PURE__ */ d(
|
|
247
|
+
D,
|
|
193
248
|
{
|
|
194
|
-
href:
|
|
195
|
-
fragmentKey:
|
|
249
|
+
href: t,
|
|
250
|
+
fragmentKey: fe
|
|
196
251
|
}
|
|
197
252
|
),
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
return
|
|
201
|
-
|
|
253
|
+
s.map((m) => {
|
|
254
|
+
const g = me(m);
|
|
255
|
+
return g ? /* @__PURE__ */ d(
|
|
256
|
+
D,
|
|
202
257
|
{
|
|
203
|
-
href:
|
|
204
|
-
fragmentKey:
|
|
258
|
+
href: g,
|
|
259
|
+
fragmentKey: he(m)
|
|
205
260
|
},
|
|
206
|
-
|
|
261
|
+
m
|
|
207
262
|
) : null;
|
|
208
263
|
}),
|
|
209
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ d(b.Provider, { value: c, children: /* @__PURE__ */ d(O.Provider, { value: i, children: /* @__PURE__ */ d(x.Provider, { value: n, children: /* @__PURE__ */ d(z.Provider, { value: null, children: /* @__PURE__ */ d(
|
|
210
265
|
"div",
|
|
211
266
|
{
|
|
212
|
-
className:
|
|
267
|
+
className: o,
|
|
213
268
|
style: { display: "contents" },
|
|
214
|
-
children: /* @__PURE__ */
|
|
269
|
+
children: /* @__PURE__ */ d(l, { ...h })
|
|
215
270
|
}
|
|
216
|
-
) }) })
|
|
271
|
+
) }) }) }) })
|
|
217
272
|
] });
|
|
218
|
-
},
|
|
219
|
-
|
|
273
|
+
}, Be = ({ onError: r, ...e }) => /* @__PURE__ */ d(K, { fallback: null, children: /* @__PURE__ */ d(W, { onError: r, children: /* @__PURE__ */ d(Z, { ...e }) }) }), be = ({ areaCode: r, options: e, retry: t }) => {
|
|
274
|
+
const n = Ne(r, {
|
|
275
|
+
suspense: !1,
|
|
276
|
+
ssr: !1,
|
|
277
|
+
pause: e == null ? void 0 : e.pause,
|
|
278
|
+
timeout: e == null ? void 0 : e.timeout
|
|
279
|
+
}), s = H(null);
|
|
280
|
+
if (y(() => {
|
|
281
|
+
var S;
|
|
282
|
+
if (n.status !== "not-found" || !n.error) return;
|
|
283
|
+
const m = V(n.error), g = JSON.stringify([r, m.kind, m.code, m.error.message]);
|
|
284
|
+
s.current !== g && (s.current = g, (S = e == null ? void 0 : e.onError) == null || S.call(e, m.error), process.env.NODE_ENV !== "production" && m.kind !== "no-variant" && console.error(
|
|
285
|
+
`[fragments] Area resolution ${m.kind}: areaCode=${r}, code=${m.code ?? "none"}`,
|
|
286
|
+
m.error
|
|
287
|
+
));
|
|
288
|
+
}, [r, e == null ? void 0 : e.onError, n.error, n.status]), (e == null ? void 0 : e.pause) === !0)
|
|
220
289
|
return null;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (n ===
|
|
226
|
-
return null;
|
|
227
|
-
const { rootFragmentId:
|
|
228
|
-
return /* @__PURE__ */
|
|
229
|
-
|
|
290
|
+
if (n.status === "idle")
|
|
291
|
+
return (e == null ? void 0 : e.fallback) ?? null;
|
|
292
|
+
if (n.status === "not-found")
|
|
293
|
+
return Q(e == null ? void 0 : e.empty, V(n.error), t);
|
|
294
|
+
if (n.status === "loading" || !n.data)
|
|
295
|
+
return (e == null ? void 0 : e.fallback) ?? null;
|
|
296
|
+
const { rootFragmentId: a, props: i, projectProperties: c, globalCssUrl: l, fragments: u, slots: E, sources: h } = n.data, o = typeof (e == null ? void 0 : e.props) == "function" ? e.props(i) : e != null && e.props ? { ...i, ...e.props } : i;
|
|
297
|
+
return /* @__PURE__ */ d(K, { fallback: (e == null ? void 0 : e.fallback) ?? null, children: /* @__PURE__ */ d(
|
|
298
|
+
Z,
|
|
230
299
|
{
|
|
231
|
-
fragmentId:
|
|
300
|
+
fragmentId: a,
|
|
232
301
|
props: o,
|
|
233
|
-
globalCssUrl:
|
|
234
|
-
projectProperties:
|
|
235
|
-
fragments:
|
|
236
|
-
slots:
|
|
302
|
+
globalCssUrl: l,
|
|
303
|
+
projectProperties: c,
|
|
304
|
+
fragments: u,
|
|
305
|
+
slots: E,
|
|
306
|
+
sources: h
|
|
237
307
|
}
|
|
308
|
+
) });
|
|
309
|
+
}, Ke = ({ areaCode: r, options: e }) => {
|
|
310
|
+
const t = v(k), [n, s] = w(0), a = t == null ? void 0 : t.$area;
|
|
311
|
+
y(() => {
|
|
312
|
+
(e == null ? void 0 : e.ssr) !== !0 || process.env.NODE_ENV === "production" || console.error(
|
|
313
|
+
"[fragments] Area option `ssr` is reserved: server resolution has been removed from the runtime; existing `ssr: false` calls continue to work unchanged."
|
|
314
|
+
);
|
|
315
|
+
}, [e == null ? void 0 : e.ssr]);
|
|
316
|
+
const i = _(() => {
|
|
317
|
+
a != null && a.resolve && (a.resolve(r).catch(() => {
|
|
318
|
+
}), s((c) => c + 1));
|
|
319
|
+
}, [a, r]);
|
|
320
|
+
return (
|
|
321
|
+
// A retry remounts the boundary and AreaInner: a repeated failure is a new
|
|
322
|
+
// telemetry event, so AreaInner intentionally calls options.onError again.
|
|
323
|
+
/* @__PURE__ */ d(W, { onError: e == null ? void 0 : e.onError, empty: e == null ? void 0 : e.empty, retry: i, children: /* @__PURE__ */ d(be, { areaCode: r, options: e, retry: i }) }, n)
|
|
238
324
|
);
|
|
239
|
-
}
|
|
240
|
-
function
|
|
241
|
-
const
|
|
325
|
+
};
|
|
326
|
+
function He({ client: r, children: e }) {
|
|
327
|
+
const t = N(
|
|
242
328
|
() => ({
|
|
243
|
-
read: (
|
|
329
|
+
read: (n) => r.$fragments.read(n)
|
|
244
330
|
}),
|
|
245
331
|
[r]
|
|
246
332
|
);
|
|
247
|
-
return /* @__PURE__ */
|
|
333
|
+
return /* @__PURE__ */ d(Ae, { value: r, children: /* @__PURE__ */ d(Ce, { value: t, children: e }) });
|
|
334
|
+
}
|
|
335
|
+
function ze(r) {
|
|
336
|
+
return (v(x) ?? J)[r];
|
|
337
|
+
}
|
|
338
|
+
function Ie(r, e) {
|
|
339
|
+
const [, t] = oe((a) => a + 1, 0), n = e(), s = H(n);
|
|
340
|
+
return s.current = n, y(() => {
|
|
341
|
+
const a = r(t);
|
|
342
|
+
return Object.is(s.current, e()) || t(), a;
|
|
343
|
+
}, [r, e]), n;
|
|
248
344
|
}
|
|
249
|
-
|
|
250
|
-
|
|
345
|
+
const B = ae.useSyncExternalStore, Me = B || ((r, e) => Ie(r, e)), ee = "offline", je = () => Promise.reject(new Error(ee));
|
|
346
|
+
function $e(r, e) {
|
|
347
|
+
var M;
|
|
348
|
+
const t = ke(), [n] = w(Ee), s = (t == null ? void 0 : t.sourceCache) ?? n, a = (M = t == null ? void 0 : t.sourceFetchers) == null ? void 0 : M[r], i = a ? "host-fetch" : "network", c = t == null ? void 0 : t.env, l = j({ source: r, target: e.target, params: e.params }), u = N(() => ({ source: r, target: e.target, params: e.params }), [l]), E = _((T) => s.subscribe(u, T), [s, u]), h = _(() => s.get(u), [s, u]), o = Me(E, h, h), m = v(b), g = v(O), S = ve(r, e.target), f = N(
|
|
349
|
+
() => m === ee ? null : ge(g[S], u.params),
|
|
350
|
+
[m, g, S, u]
|
|
351
|
+
), [C, I] = w(null);
|
|
352
|
+
return y(() => {
|
|
353
|
+
(o == null ? void 0 : o.status) === "ready" && C !== null && I(null);
|
|
354
|
+
}, [o, C]), y(() => {
|
|
355
|
+
f && !f.ok && o === void 0 && console.warn(`[useSource] ${S}: ${f.reason}`);
|
|
356
|
+
}, [S, f == null ? void 0 : f.ok, f && !f.ok ? f.reason : void 0, o === void 0]), y(() => {
|
|
357
|
+
if (f && !f.ok || (o == null ? void 0 : o.status) === "ready" || C === l) return;
|
|
358
|
+
I(l);
|
|
359
|
+
const T = f && f.ok ? () => ye({ url: f.url, init: f.init }, { fetcher: a, timeout: c == null ? void 0 : c.timeout }).then((re) => (c != null && c.debug && console.info(`[useSource] loaded ${j(u)} origin=${i}`), re)) : je;
|
|
360
|
+
s.load(u, T, i);
|
|
361
|
+
}, [s, u, l, o, C, f, a, i, c == null ? void 0 : c.timeout, c == null ? void 0 : c.debug]), (o == null ? void 0 : o.status) === "ready" ? { data: o.data ?? void 0, loading: !1 } : (o == null ? void 0 : o.status) === "pending" ? { data: void 0, loading: !0 } : f && !f.ok ? { data: void 0, loading: !1 } : { data: void 0, loading: C !== l };
|
|
251
362
|
}
|
|
252
|
-
|
|
253
|
-
|
|
363
|
+
const Ge = $e;
|
|
364
|
+
function Ye(r) {
|
|
365
|
+
return Se({ ...r, inject: Y });
|
|
254
366
|
}
|
|
255
367
|
export {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
368
|
+
L as AREA_UNRESOLVED,
|
|
369
|
+
Ke as Area,
|
|
370
|
+
Be as FragmentRenderer,
|
|
371
|
+
D as FragmentStylesheet,
|
|
372
|
+
Qe as FragmentsApiVersionError,
|
|
373
|
+
We as FragmentsAreaError,
|
|
374
|
+
k as FragmentsClientContext,
|
|
375
|
+
Ae as FragmentsClientProvider,
|
|
376
|
+
Xe as FragmentsLoadError,
|
|
377
|
+
He as FragmentsProvider,
|
|
378
|
+
z as InstanceIdContext,
|
|
379
|
+
F as ModulesMapContext,
|
|
380
|
+
Ce as ModulesMapProvider,
|
|
381
|
+
x as ProjectPropertiesContext,
|
|
382
|
+
Ye as createBrowserClient,
|
|
383
|
+
Ze as createSourceCache,
|
|
384
|
+
J as defaultProjectProperties,
|
|
385
|
+
Y as injectStylesheet,
|
|
386
|
+
Ne as useArea,
|
|
387
|
+
pe as useCssChunk,
|
|
388
|
+
Pe as useFragmentComponent,
|
|
389
|
+
Ue as useFragmentMetrics,
|
|
390
|
+
Te as useFragmentStylesheet,
|
|
391
|
+
ze as useProjectProperty,
|
|
392
|
+
Ge as useSource
|
|
279
393
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(l,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("react/jsx-runtime"),require("react"),require("@fragmentsx/fragments-client")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","@fragmentsx/fragments-client"],u):(l=typeof globalThis<"u"?globalThis:l||self,u(l.FragmentsRuntimeReact={},l.jsxRuntime,l.React,l.fragmentsClient))})(this,function(l,u,a,m){"use strict";const g=a.createContext(null);g.displayName="FragmentsClientContext";function j(r){return u.jsx(g.Provider,{value:r.value,children:r.children})}const P=a.createContext(null);P.displayName="InstanceIdContext";const E=a.createContext(null);E.displayName="ModulesMapContext";function w({value:r,children:e}){return u.jsx(E.Provider,{value:r,children:e})}function p(){const r=a.useContext(g);return a.useMemo(()=>({reachGoal:e=>{var n,t;(t=(n=r==null?void 0:r.$metrics)==null?void 0:n.reachGoal)==null||t.call(n,e)}}),[r])}function I(r){const e=a.useContext(E);if(!e)throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");return e.read(r)}const B=typeof window<"u",F=Object.freeze({rootFragmentId:0,variantId:null,props:{},projectProperties:{},globalCssUrl:null,fragments:[],slots:{}});function T(r,e){const n=a.useContext(g);if(!n)throw new Error("[useArea] No FragmentsClientProvider in tree");const t=n.$area;if(!(t!=null&&t.read))throw new Error("[useArea] $area plugin not mounted");const s=(e==null?void 0:e.suspense)??!0,c=(e==null?void 0:e.pause)===!0||!B&&(e==null?void 0:e.ssr)===!1,d=(e==null?void 0:e.timeout)!=null?{timeout:e.timeout}:void 0,[,h]=a.useState(0);if(a.useEffect(()=>{if(s||c)return;let o=!0;return Promise.resolve(t.resolve(r,d)).catch(()=>{}).finally(()=>{o&&h(f=>f+1)}),()=>{o=!1}},[r,s,e==null?void 0:e.pause,e==null?void 0:e.timeout,e==null?void 0:e.ssr]),s)return c?F:(t.has(r)||Promise.resolve(t.resolve(r,d)).catch(()=>{}),t.read(r));if(c)return{status:"idle",data:null,error:null};if(t.has(r))try{return{status:"ready",data:t.read(r),error:null}}catch(o){return{status:"not-found",data:null,error:o instanceof Error?o:new Error(String(o))}}return Promise.resolve(t.resolve(r,d)).catch(()=>{}),{status:"loading",data:null,error:null}}const _=typeof window<"u",D=3e3,v=new Map,A=(r,e)=>{if(!_){const i=()=>{};return i.loaded=Promise.resolve(),i}const n=v.get(e);if(n){n.refCount+=1;const i=()=>{n.refCount-=1,n.refCount===0&&(n.clearReadyTimer(),n.linkEl.remove(),v.delete(e))};return i.loaded=n.loaded,i}const t=document.createElement("link");t.rel="stylesheet",t.href=r,t.setAttribute("data-fragment-key",e);let s;const c=new Promise(i=>{s=i}),d=()=>{o(),s()},h=setTimeout(d,D),o=()=>clearTimeout(h);t.addEventListener("load",d),t.addEventListener("error",d),document.head.appendChild(t);const f={refCount:1,linkEl:t,loaded:c,clearReadyTimer:o};v.set(e,f);const C=()=>{f.refCount-=1,f.refCount===0&&(f.clearReadyTimer(),f.linkEl.remove(),v.delete(e))};return C.loaded=c,C},V=_?a.useLayoutEffect:a.useEffect;function b(r,e){V(()=>A(r,e),[r,e])}const R=parseInt(a.version.split(".")[0],10)>=19;function S({href:r,fragmentKey:e}){return R?u.jsx("link",{rel:"stylesheet",href:r,precedence:"default","data-fragment-key":e}):(b(r,e),null)}function U(r){}const M={},y=a.createContext(null);y.displayName="ProjectPropertiesContext";class N extends a.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,n){var t,s;process.env.NODE_ENV!=="production"&&console.error("[fragments] Area error:",e,n.componentStack),(s=(t=this.props).onError)==null||s.call(t,e)}render(){return this.state.hasError?null:this.props.children}}function O(r,e){if(!r)return{};const n={};for(const t of Object.keys(r))n[t]=$(r[t],e);return n}function $(r,e){return Array.isArray(r)?r.map((n,t)=>n===null?null:L(n,e,t)):L(r,e)}function L(r,e,n){let t;try{t=e(r.fragmentId)}catch(c){if(c!=null&&typeof c.then=="function")throw c;return console.warn(`[FragmentRenderer] Slot fragment ${r.fragmentId} failed to load — rendering empty hole`,c),null}const s=O(r.slots,e);return a.createElement(t,{key:n,...r.props,...s})}const k=({fragmentId:r,props:e,globalCssUrl:n=null,projectProperties:t=M,fragments:s=[r],slots:c})=>{const d=I(r),h=a.useContext(E);if(!h)throw new Error("[FragmentRendererInner] No ModulesMapProvider in tree");const o=O(c,h.read),f={...e??{},...o},C=s.length>0?s.map(m.toScopeClassName).join(" "):void 0;return u.jsxs(u.Fragment,{children:[n!=null&&u.jsx(S,{href:n,fragmentKey:m.AREA_GLOBAL_CSS_KEY}),s.map(i=>{const x=m.resolveStylesHref(i);return x?u.jsx(S,{href:x,fragmentKey:m.fragmentCssKey(i)},i):null}),u.jsx(y.Provider,{value:t,children:u.jsx(P.Provider,{value:null,children:u.jsx("div",{className:C,style:{display:"contents"},children:u.jsx(d,{...f})})})})]})},q=({onError:r,...e})=>u.jsx(a.Suspense,{fallback:null,children:u.jsx(N,{onError:r,children:u.jsx(k,{...e})})}),G=({areaCode:r,options:e})=>{if((e==null?void 0:e.pause)===!0)return null;const n=T(r,{timeout:e==null?void 0:e.timeout,ssr:e==null?void 0:e.ssr});if(n===F)return null;const{rootFragmentId:t,props:s,projectProperties:c,globalCssUrl:d,fragments:h,slots:o}=n,f=typeof(e==null?void 0:e.props)=="function"?e.props(s):e!=null&&e.props?{...s,...e.props}:s;return u.jsx(k,{fragmentId:t,props:f,globalCssUrl:d,projectProperties:c,fragments:h,slots:o})},K=({areaCode:r,options:e})=>u.jsx(a.Suspense,{fallback:(e==null?void 0:e.fallback)??null,children:u.jsx(N,{onError:e==null?void 0:e.onError,children:u.jsx(G,{areaCode:r,options:e})})});function Y({client:r,children:e}){const n=a.useMemo(()=>({read:t=>r.$fragments.read(t)}),[r]);return u.jsx(j,{value:r,children:u.jsx(w,{value:n,children:e})})}function H(r){return(a.useContext(y)??M)[r]}function J(r){return m.createFragmentsClient({...r,inject:A})}Object.defineProperty(l,"FragmentsApiVersionError",{enumerable:!0,get:()=>m.FragmentsApiVersionError}),Object.defineProperty(l,"FragmentsAreaError",{enumerable:!0,get:()=>m.FragmentsAreaError}),Object.defineProperty(l,"FragmentsLoadError",{enumerable:!0,get:()=>m.FragmentsLoadError}),l.AREA_UNRESOLVED=F,l.Area=K,l.FragmentRenderer=q,l.FragmentStylesheet=S,l.FragmentsClientContext=g,l.FragmentsClientProvider=j,l.FragmentsProvider=Y,l.InstanceIdContext=P,l.ModulesMapContext=E,l.ModulesMapProvider=w,l.ProjectPropertiesContext=y,l.createBrowserClient=J,l.defaultProjectProperties=M,l.injectStylesheet=A,l.useArea=T,l.useCssChunk=U,l.useFragmentComponent=I,l.useFragmentMetrics=p,l.useFragmentStylesheet=b,l.useProjectProperty=H,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(s,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("react/jsx-runtime"),require("react"),require("@fragmentsx/fragments-client")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","@fragmentsx/fragments-client"],l):(s=typeof globalThis<"u"?globalThis:s||self,l(s.FragmentsRuntimeReact={},s.jsxRuntime,s.React,s.fragmentsClient))})(this,function(s,l,u,h){"use strict";function ee(r){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const t in r)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>r[t]})}}return e.default=r,Object.freeze(e)}const re=ee(u),P=u.createContext(null);P.displayName="FragmentsClientContext";function $(r){return l.jsx(P.Provider,{value:r.value,children:r.children})}function te(){return u.useContext(P)}const N=u.createContext(null);N.displayName="InstanceIdContext";const A=u.createContext(null);A.displayName="ModulesMapContext";function D({value:r,children:e}){return l.jsx(A.Provider,{value:r,children:e})}function ne(){const r=u.useContext(P);return u.useMemo(()=>({reachGoal:e=>{var t,n;(n=(t=r==null?void 0:r.$metrics)==null?void 0:t.reachGoal)==null||n.call(t,e)}}),[r])}function L(r){const e=u.useContext(A);if(!e)throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");return e.read(r)}const V=typeof window<"u",O=Object.freeze({rootFragmentId:0,variantId:null,props:{},projectProperties:{},globalCssUrl:null,fragments:[],slots:{},sources:{}});function w(r){const e=r.$area;if(!(e!=null&&e.read))throw new Error("[useArea] $area plugin not mounted");return e}function U(r,e){const t=u.useContext(P);if(!t)throw new Error("[useArea] No FragmentsClientProvider in tree");const n=(e==null?void 0:e.suspense)??!0,c=(e==null?void 0:e.pause)===!0||!V&&(e==null?void 0:e.ssr)===!1,a=(e==null?void 0:e.timeout)!=null?{timeout:e.timeout}:void 0,[,m]=u.useState(0);if(u.useEffect(()=>{if(n||c)return;const f=w(t);let o=!0;return Promise.resolve(f.resolve(r,a)).catch(()=>{}).finally(()=>{o&&m(y=>y+1)}),()=>{o=!1}},[r,n,e==null?void 0:e.pause,e==null?void 0:e.timeout,e==null?void 0:e.ssr]),n){if(c)return O;const f=w(t);if(f.has(r)||Promise.resolve(f.resolve(r,a)).catch(()=>{}),!V)try{return f.read(r)}catch(o){if(o!=null&&typeof o.then=="function")throw o;return process.env.NODE_ENV!=="production"&&console.error(`[useArea] Area ${r} remained unresolved on the server because its cache reached a terminal state`,o),O}return f.read(r)}if(c)return{status:"idle",data:null,error:null};const d=w(t);if(d.has(r))try{return{status:"ready",data:d.read(r),error:null}}catch(f){return{status:"not-found",data:null,error:f instanceof Error?f:new Error(String(f))}}return Promise.resolve(d.resolve(r,a)).catch(()=>{}),{status:"loading",data:null,error:null}}const B=typeof window<"u",ue=3e3,k=new Map,T=(r,e)=>{if(!B){const v=()=>{};return v.loaded=Promise.resolve(),v}const t=k.get(e);if(t){t.refCount+=1;const v=()=>{t.refCount-=1,t.refCount===0&&(t.clearReadyTimer(),t.linkEl.remove(),k.delete(e))};return v.loaded=t.loaded,v}const n=document.createElement("link");n.rel="stylesheet",n.href=r,n.setAttribute("data-fragment-key",e);let c;const a=new Promise(v=>{c=v}),m=()=>{f(),c()},d=setTimeout(m,ue),f=()=>clearTimeout(d);n.addEventListener("load",m),n.addEventListener("error",m),document.head.appendChild(n);const o={refCount:1,linkEl:n,loaded:a,clearReadyTimer:f};k.set(e,o);const y=()=>{o.refCount-=1,o.refCount===0&&(o.clearReadyTimer(),o.linkEl.remove(),k.delete(e))};return y.loaded=a,y},se=B?u.useLayoutEffect:u.useEffect;function K(r,e){se(()=>T(r,e),[r,e])}const ae=parseInt(u.version.split(".")[0],10)>=19;function M({href:r,fragmentKey:e}){return ae?l.jsx("link",{rel:"stylesheet",href:r,precedence:"default","data-fragment-key":e}):(K(r,e),null)}function ce(r){}const _={},b=u.createContext(null);b.displayName="ProjectPropertiesContext";const z=Object.freeze({}),j=u.createContext(z);j.displayName="SourceTransportsContext";const I=u.createContext("live");I.displayName="SourceNetworkContext";function H(r){const e=r instanceof Error?r:new Error(String(r));if(!(e instanceof h.FragmentsAreaError))return{kind:"failed",error:e};const{code:t}=e;return t==="NO_ACTIVE_VARIANT"?{kind:"no-variant",code:t,error:e}:t==="AREA_NOT_FOUND"||t==="NO_PUBLISHED_SNAPSHOT"||t==="NESTED_SNAPSHOT_MISSING"?{kind:"misconfigured",code:t,error:e}:{kind:"failed",code:t,error:e}}function G(r,e,t){return typeof r=="function"?r(e,t):r??null}const oe=()=>{};function Y(r){return r instanceof Error?r:new Error(String(r))}class q extends u.Component{constructor(){super(...arguments),this.state={hasError:!1,error:null}}static getDerivedStateFromError(e){return{hasError:!0,error:Y(e)}}componentDidCatch(e,t){var c,a;const n=Y(e);process.env.NODE_ENV!=="production"&&console.error("[fragments] Area error:",n,t.componentStack),(a=(c=this.props).onError)==null||a.call(c,n)}render(){if(this.state.hasError){const e={kind:"failed",error:this.state.error??new Error("Unknown Area error")};try{return G(this.props.empty,e,this.props.retry??oe)}catch{return null}}return this.props.children}}function J(r,e){if(!r)return{};const t={};for(const n of Object.keys(r))t[n]=le(r[n],e);return t}function le(r,e){return Array.isArray(r)?r.map((t,n)=>t===null?null:p(t,e,n)):p(r,e)}function p(r,e,t){let n;try{n=e(r.fragmentId)}catch(a){if(a!=null&&typeof a.then=="function")throw a;return console.warn(`[FragmentRenderer] Slot fragment ${r.fragmentId} failed to load — rendering empty hole`,a),null}const c=J(r.slots,e);return u.createElement(n,{key:t,...r.props,...c})}const Q=({fragmentId:r,props:e,globalCssUrl:t=null,projectProperties:n=_,fragments:c=[r],slots:a,sources:m=z,sourceNetwork:d="live"})=>{const f=L(r),o=u.useContext(A);if(!o)throw new Error("[FragmentRendererInner] No ModulesMapProvider in tree");const y=J(a,o.read),v={...e??{},...y},i=c.length>0?c.map(h.toScopeClassName).join(" "):void 0;return l.jsxs(l.Fragment,{children:[t!=null&&l.jsx(M,{href:t,fragmentKey:h.AREA_GLOBAL_CSS_KEY}),c.map(g=>{const S=h.resolveStylesHref(g);return S?l.jsx(M,{href:S,fragmentKey:h.fragmentCssKey(g)},g):null}),l.jsx(I.Provider,{value:d,children:l.jsx(j.Provider,{value:m,children:l.jsx(b.Provider,{value:n,children:l.jsx(N.Provider,{value:null,children:l.jsx("div",{className:i,style:{display:"contents"},children:l.jsx(f,{...v})})})})})})]})},de=({onError:r,...e})=>l.jsx(u.Suspense,{fallback:null,children:l.jsx(q,{onError:r,children:l.jsx(Q,{...e})})}),fe=({areaCode:r,options:e,retry:t})=>{const n=U(r,{suspense:!1,ssr:!1,pause:e==null?void 0:e.pause,timeout:e==null?void 0:e.timeout}),c=u.useRef(null);if(u.useEffect(()=>{var C;if(n.status!=="not-found"||!n.error)return;const g=H(n.error),S=JSON.stringify([r,g.kind,g.code,g.error.message]);c.current!==S&&(c.current=S,(C=e==null?void 0:e.onError)==null||C.call(e,g.error),process.env.NODE_ENV!=="production"&&g.kind!=="no-variant"&&console.error(`[fragments] Area resolution ${g.kind}: areaCode=${r}, code=${g.code??"none"}`,g.error))},[r,e==null?void 0:e.onError,n.error,n.status]),(e==null?void 0:e.pause)===!0)return null;if(n.status==="idle")return(e==null?void 0:e.fallback)??null;if(n.status==="not-found")return G(e==null?void 0:e.empty,H(n.error),t);if(n.status==="loading"||!n.data)return(e==null?void 0:e.fallback)??null;const{rootFragmentId:a,props:m,projectProperties:d,globalCssUrl:f,fragments:o,slots:y,sources:v}=n.data,i=typeof(e==null?void 0:e.props)=="function"?e.props(m):e!=null&&e.props?{...m,...e.props}:m;return l.jsx(u.Suspense,{fallback:(e==null?void 0:e.fallback)??null,children:l.jsx(Q,{fragmentId:a,props:i,globalCssUrl:f,projectProperties:d,fragments:o,slots:y,sources:v})})},ie=({areaCode:r,options:e})=>{const t=u.useContext(P),[n,c]=u.useState(0),a=t==null?void 0:t.$area;u.useEffect(()=>{(e==null?void 0:e.ssr)!==!0||process.env.NODE_ENV==="production"||console.error("[fragments] Area option `ssr` is reserved: server resolution has been removed from the runtime; existing `ssr: false` calls continue to work unchanged.")},[e==null?void 0:e.ssr]);const m=u.useCallback(()=>{a!=null&&a.resolve&&(a.resolve(r).catch(()=>{}),c(d=>d+1))},[a,r]);return l.jsx(q,{onError:e==null?void 0:e.onError,empty:e==null?void 0:e.empty,retry:m,children:l.jsx(fe,{areaCode:r,options:e,retry:m})},n)};function me({client:r,children:e}){const t=u.useMemo(()=>({read:n=>r.$fragments.read(n)}),[r]);return l.jsx($,{value:r,children:l.jsx(D,{value:t,children:e})})}function Ee(r){return(u.useContext(b)??_)[r]}function he(r,e){const[,t]=u.useReducer(a=>a+1,0),n=e(),c=u.useRef(n);return c.current=n,u.useEffect(()=>{const a=r(t);return Object.is(c.current,e())||t(),a},[r,e]),n}const W=re.useSyncExternalStore,ge=W||((r,e)=>he(r,e)),X="offline",ve=()=>Promise.reject(new Error(X));function ye(r,e){var R;const t=te(),[n]=u.useState(h.createSourceCache),c=(t==null?void 0:t.sourceCache)??n,a=(R=t==null?void 0:t.sourceFetchers)==null?void 0:R[r],m=a?"host-fetch":"network",d=t==null?void 0:t.env,f=h.sourceCallKey({source:r,target:e.target,params:e.params}),o=u.useMemo(()=>({source:r,target:e.target,params:e.params}),[f]),y=u.useCallback(x=>c.subscribe(o,x),[c,o]),v=u.useCallback(()=>c.get(o),[c,o]),i=ge(y,v,v),g=u.useContext(I),S=u.useContext(j),C=h.sourceTransportKey(r,e.target),E=u.useMemo(()=>g===X?null:h.resolveSourceRequest(S[C],o.params),[g,S,C,o]),[F,Z]=u.useState(null);return u.useEffect(()=>{(i==null?void 0:i.status)==="ready"&&F!==null&&Z(null)},[i,F]),u.useEffect(()=>{E&&!E.ok&&i===void 0&&console.warn(`[useSource] ${C}: ${E.reason}`)},[C,E==null?void 0:E.ok,E&&!E.ok?E.reason:void 0,i===void 0]),u.useEffect(()=>{if(E&&!E.ok||(i==null?void 0:i.status)==="ready"||F===f)return;Z(f);const x=E&&E.ok?()=>h.runSourceFetch({url:E.url,init:E.init},{fetcher:a,timeout:d==null?void 0:d.timeout}).then(Ce=>(d!=null&&d.debug&&console.info(`[useSource] loaded ${h.sourceCallKey(o)} origin=${m}`),Ce)):ve;c.load(o,x,m)},[c,o,f,i,F,E,a,m,d==null?void 0:d.timeout,d==null?void 0:d.debug]),(i==null?void 0:i.status)==="ready"?{data:i.data??void 0,loading:!1}:(i==null?void 0:i.status)==="pending"?{data:void 0,loading:!0}:E&&!E.ok?{data:void 0,loading:!1}:{data:void 0,loading:F!==f}}const Se=ye;function Pe(r){return h.createFragmentsClient({...r,inject:T})}Object.defineProperty(s,"FragmentsApiVersionError",{enumerable:!0,get:()=>h.FragmentsApiVersionError}),Object.defineProperty(s,"FragmentsAreaError",{enumerable:!0,get:()=>h.FragmentsAreaError}),Object.defineProperty(s,"FragmentsLoadError",{enumerable:!0,get:()=>h.FragmentsLoadError}),Object.defineProperty(s,"createSourceCache",{enumerable:!0,get:()=>h.createSourceCache}),s.AREA_UNRESOLVED=O,s.Area=ie,s.FragmentRenderer=de,s.FragmentStylesheet=M,s.FragmentsClientContext=P,s.FragmentsClientProvider=$,s.FragmentsProvider=me,s.InstanceIdContext=N,s.ModulesMapContext=A,s.ModulesMapProvider=D,s.ProjectPropertiesContext=b,s.createBrowserClient=Pe,s.defaultProjectProperties=_,s.injectStylesheet=T,s.useArea=U,s.useCssChunk=ce,s.useFragmentComponent=L,s.useFragmentMetrics=ne,s.useFragmentStylesheet=K,s.useProjectProperty=Ee,s.useSource=Se,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fragmentsx/runtime-react",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.2.0-dev-
|
|
4
|
+
"version": "0.2.0-dev-20260928114300",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@graph-state/core": "^0.13.3",
|
|
35
|
-
"@fragmentsx/fragments-client": "0.2.0-dev-
|
|
35
|
+
"@fragmentsx/fragments-client": "0.2.0-dev-20260928114300"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@testing-library/jest-dom": "^6.6.3",
|