@fragmentsx/runtime-react 0.1.0 → 0.2.0-dev-20260831061037
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 +62 -11
- package/dist/index.d.ts +61 -4
- package/dist/index.es.js +132 -104
- package/dist/index.umd.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,12 +8,11 @@ React.
|
|
|
8
8
|
## Что это решает
|
|
9
9
|
|
|
10
10
|
Скомпилированный сервером фрагмент — это ESM-артефакт, который нужно
|
|
11
|
-
загрузить, смонтировать в дерево React, подключить его стили и дать
|
|
11
|
+
загрузить, смонтировать в дерево React, подключить его стили и дать доступ
|
|
12
12
|
к метрикам и переменным области. `runtime-react` закрывает весь этот путь:
|
|
13
13
|
|
|
14
|
-
- `FragmentsProvider`
|
|
15
|
-
|
|
16
|
-
- `Area` / `FragmentRenderer` — резолвинг и рендер области/фрагмента;
|
|
14
|
+
- `FragmentsProvider` — контекст клиента на дерево приложения;
|
|
15
|
+
- `Area` / `FragmentRenderer` — резолвинг области и рендер фрагмента;
|
|
17
16
|
- `useFragmentComponent`, `useFragmentStylesheet`, `FragmentStylesheet` —
|
|
18
17
|
подгрузка компонента и его CSS;
|
|
19
18
|
- `useFragmentMetrics`, `useArea`, `useProjectProperty` — доступ к метрикам,
|
|
@@ -25,27 +24,79 @@ React.
|
|
|
25
24
|
pnpm add @fragmentsx/runtime-react @fragmentsx/fragments-client react react-dom
|
|
26
25
|
```
|
|
27
26
|
|
|
27
|
+
Пакет объявляет `react` в `peerDependencies` (`^17 || ^18 || ^19`).
|
|
28
|
+
|
|
29
|
+
Если приложение собирается через Vite — поставьте ещё плагин, который
|
|
30
|
+
резолвит bare imports внутри загружаемых артефактов:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add -D @fragmentsx/vite-plugin
|
|
34
|
+
```
|
|
35
|
+
|
|
28
36
|
## Использование
|
|
29
37
|
|
|
30
38
|
```tsx
|
|
31
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
createBrowserClient,
|
|
41
|
+
FragmentsProvider,
|
|
42
|
+
Area,
|
|
43
|
+
} from '@fragmentsx/runtime-react';
|
|
32
44
|
|
|
33
45
|
const client = createBrowserClient({
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
apiToken: import.meta.env.VITE_FRAGMENTS_API_TOKEN,
|
|
47
|
+
backendEndpoint: 'https://api.example.com',
|
|
36
48
|
});
|
|
37
49
|
|
|
38
50
|
function App() {
|
|
39
51
|
return (
|
|
40
52
|
<FragmentsProvider client={client}>
|
|
41
|
-
<Area
|
|
53
|
+
<Area areaCode="home" />
|
|
42
54
|
</FragmentsProvider>
|
|
43
55
|
);
|
|
44
56
|
}
|
|
45
57
|
```
|
|
46
58
|
|
|
59
|
+
`apiToken` обязателен. `backendEndpoint` — источник манифеста области; если
|
|
60
|
+
не передан, клиент бьётся в `window.location.origin`, что удобно при
|
|
61
|
+
same-origin проксировании `/api` на публичный API площадки.
|
|
62
|
+
|
|
63
|
+
`Area` сама разрешает область и внутри себя обёрнута в `Suspense` — пока
|
|
64
|
+
манифест грузится, поддерево пустое. Под капотом:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
<Area areaCode> → GET <backendEndpoint>/api/area/<code>/compiled
|
|
68
|
+
→ manifest.fragments[*].moduleUrl → import(артефакт)
|
|
69
|
+
→ <FragmentStylesheet href={cssUrl}/> + рендер фрагмента
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Рендер конкретного фрагмента
|
|
73
|
+
|
|
74
|
+
Когда область разрешать не нужно, используйте `FragmentRenderer` напрямую:
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { FragmentRenderer } from '@fragmentsx/runtime-react';
|
|
78
|
+
|
|
79
|
+
<FragmentRenderer fragmentId={42} props={{ title: 'Привет' }} />
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`AreaProps` — `{ areaCode: string; options?: { timeout?, pause?, ssr? } }`.
|
|
83
|
+
`FragmentRendererProps` — `{ fragmentId: number; props?; globalCssUrl?;
|
|
84
|
+
projectProperties?; onError? }`.
|
|
85
|
+
|
|
86
|
+
## Обработка ошибок
|
|
87
|
+
|
|
88
|
+
Пакет реэкспортирует типизированные ошибки транспорта, чтобы их можно было
|
|
89
|
+
различать в границах ошибок приложения:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import {
|
|
93
|
+
FragmentsAreaError,
|
|
94
|
+
FragmentsApiVersionError,
|
|
95
|
+
FragmentsLoadError,
|
|
96
|
+
} from '@fragmentsx/runtime-react';
|
|
97
|
+
```
|
|
98
|
+
|
|
47
99
|
## Пара с fragments-client
|
|
48
100
|
|
|
49
|
-
`runtime-react` зависит от `@fragmentsx/fragments-client` как от
|
|
50
|
-
ядра
|
|
51
|
-
и обновлять пакеты стоит вместе.
|
|
101
|
+
`runtime-react` зависит от `@fragmentsx/fragments-client` как от
|
|
102
|
+
транспортного ядра — устанавливать и обновлять пакеты стоит вместе.
|
package/dist/index.d.ts
CHANGED
|
@@ -20,13 +20,33 @@ import { ReactNode } from 'react';
|
|
|
20
20
|
export declare const Area: FC<AreaProps>;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Сентинел нерезолвленной области — возвращается вместо чтения `$area.read`,
|
|
24
|
+
* когда на сервере `options.ssr === false`, либо когда `options.pause === true`
|
|
25
|
+
* (suspense-режим).
|
|
26
|
+
*
|
|
27
|
+
* Совместим с `UseAreaResult` по форме (тип возврата хука не расширяется),
|
|
28
|
+
* поэтому правка остаётся minor: потребитель, передающий `rootFragmentId`
|
|
29
|
+
* в проп типа `number`, продолжает компилироваться. Заморожен — сравнение
|
|
30
|
+
* по ссылке в `Area.tsx` не должно ломаться мутацией снаружи.
|
|
31
|
+
*/
|
|
32
|
+
export declare const AREA_UNRESOLVED: UseAreaResult;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Props для Area компонента (D-09, сокращён Phase 73 B-13; расширен quick 260830-rvp):
|
|
24
36
|
* - areaCode — строковый код области (Area.code в backend schema)
|
|
25
37
|
* - options.pause — пропустить рендер (conditional skip per legacy contract)
|
|
26
38
|
* - options.timeout — network timeout для $area.resolve fetch
|
|
27
39
|
* - options.ssr — отключить auto-resolve в SSR environment (default `true`);
|
|
28
40
|
* в browser auto-resolve запускается всегда. Параллель к render-react
|
|
29
41
|
* Area options.ssr.
|
|
42
|
+
* - options.props (INT-03) — объект мержится поверх серверных props (ключи
|
|
43
|
+
* потребителя выигрывают), функция вызывается с серверными props и её
|
|
44
|
+
* результат уходит в артефакт целиком. Обе формы поддержаны намеренно —
|
|
45
|
+
* паритет с legacy render-react, с которого мигрирует потребитель.
|
|
46
|
+
* - options.fallback (INT-04) — узел, видимый до разрешения области; default
|
|
47
|
+
* `null` (прежнее поведение).
|
|
48
|
+
* - options.onError (INT-04) — вызывается при броске внутри поддерева;
|
|
49
|
+
* default — только dev-лог границы (прежнее поведение).
|
|
30
50
|
*/
|
|
31
51
|
export declare interface AreaProps {
|
|
32
52
|
areaCode: string;
|
|
@@ -34,6 +54,9 @@ export declare interface AreaProps {
|
|
|
34
54
|
timeout?: number;
|
|
35
55
|
pause?: boolean;
|
|
36
56
|
ssr?: boolean;
|
|
57
|
+
props?: Record<string, unknown> | ((serverProps: Record<string, unknown>) => Record<string, unknown>);
|
|
58
|
+
fallback?: ReactNode;
|
|
59
|
+
onError?: (error: Error) => void;
|
|
37
60
|
};
|
|
38
61
|
}
|
|
39
62
|
|
|
@@ -203,7 +226,15 @@ export declare interface ReachGoalInfo {
|
|
|
203
226
|
campaignId?: number;
|
|
204
227
|
}
|
|
205
228
|
|
|
206
|
-
|
|
229
|
+
/** Suspense-режим (по умолчанию либо явный `suspense: true`) — прежний throw-протокол. */
|
|
230
|
+
export declare function useArea(areaCode: string, options?: UseAreaOptions & {
|
|
231
|
+
suspense?: true;
|
|
232
|
+
}): UseAreaResult;
|
|
233
|
+
|
|
234
|
+
/** Не-suspense режим (INT-05) — явный `suspense: false` возвращает состояние вместо throw. */
|
|
235
|
+
export declare function useArea(areaCode: string, options: UseAreaOptions & {
|
|
236
|
+
suspense: false;
|
|
237
|
+
}): UseAreaState;
|
|
207
238
|
|
|
208
239
|
/**
|
|
209
240
|
* Опции хука. По дизайну API параллелен render-react useArea:
|
|
@@ -211,16 +242,22 @@ export declare function useArea(areaCode: string, options?: UseAreaOptions): Use
|
|
|
211
242
|
* - `ssr` — стартовать ли auto-resolve на сервере (default `true`, чтобы
|
|
212
243
|
* Next.js getServerSideProps мог hydration'ить с прогретым кэшем).
|
|
213
244
|
* В browser environment auto-resolve всегда включён.
|
|
245
|
+
* - `pause` (INT-06) — пропустить резолв и чтение кэша вовсе; паритет
|
|
246
|
+
* с `AreaProps.options.pause`.
|
|
247
|
+
* - `suspense` (INT-05) — `false` переключает хук на `UseAreaState` вместо
|
|
248
|
+
* throw-протокола; по умолчанию `true` (прежнее поведение).
|
|
214
249
|
*/
|
|
215
|
-
declare interface UseAreaOptions {
|
|
250
|
+
export declare interface UseAreaOptions {
|
|
216
251
|
timeout?: number;
|
|
217
252
|
ssr?: boolean;
|
|
253
|
+
pause?: boolean;
|
|
254
|
+
suspense?: boolean;
|
|
218
255
|
}
|
|
219
256
|
|
|
220
257
|
/**
|
|
221
258
|
* Result shape возвращаемый useArea — зеркалирует AreaResolveResult из client-core.
|
|
222
259
|
*/
|
|
223
|
-
declare interface UseAreaResult {
|
|
260
|
+
export declare interface UseAreaResult {
|
|
224
261
|
rootFragmentId: number;
|
|
225
262
|
/**
|
|
226
263
|
* Phase 73, B-02/B-06: значения props корневого артефакта, разрешённые сервером
|
|
@@ -244,6 +281,26 @@ declare interface UseAreaResult {
|
|
|
244
281
|
globalCssUrl: string | null;
|
|
245
282
|
}
|
|
246
283
|
|
|
284
|
+
/**
|
|
285
|
+
* Состояние, возвращаемое `useArea(code, {suspense:false})` вместо throw.
|
|
286
|
+
*/
|
|
287
|
+
export declare interface UseAreaState {
|
|
288
|
+
status: UseAreaStatus;
|
|
289
|
+
data: UseAreaResult | null;
|
|
290
|
+
error: Error | null;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Union статуса не-suspense режима (quick 260830-rvp, INT-05):
|
|
295
|
+
* - `idle` — пауза (`options.pause`) либо серверный пропуск (`ssr:false` на сервере).
|
|
296
|
+
* - `loading` — кэш пуст, резолв запущен (идемпотентно), данных ещё нет.
|
|
297
|
+
* - `ready` — терминальный кэш-хит, данные доступны.
|
|
298
|
+
* - `not-found` — терминальная ошибка резолва (сохранённая в rejected-кэше);
|
|
299
|
+
* отдельного статуса под сетевой сбой нет намеренно — оба исхода для площадки
|
|
300
|
+
* означают «показать свой шаблон», различие доступно через поле `error`.
|
|
301
|
+
*/
|
|
302
|
+
export declare type UseAreaStatus = "idle" | "loading" | "ready" | "not-found";
|
|
303
|
+
|
|
247
304
|
/**
|
|
248
305
|
* useCssChunk — no-op stub для compiled fragments.
|
|
249
306
|
*
|
package/dist/index.es.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { createContext as
|
|
3
|
-
import { createFragmentsClient as
|
|
4
|
-
import { FragmentsApiVersionError as
|
|
5
|
-
const
|
|
1
|
+
import { jsx as u, jsxs as N, Fragment as k } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as m, useContext as f, useMemo as C, useState as I, useEffect as P, useLayoutEffect as R, version as b, Component as p, Suspense as y } from "react";
|
|
3
|
+
import { createFragmentsClient as _ } from "@fragmentsx/fragments-client";
|
|
4
|
+
import { FragmentsApiVersionError as le, FragmentsAreaError as se, FragmentsLoadError as ae } from "@fragmentsx/fragments-client";
|
|
5
|
+
const o = m(
|
|
6
6
|
null
|
|
7
7
|
);
|
|
8
|
-
|
|
9
|
-
function
|
|
10
|
-
return /* @__PURE__ */ o
|
|
8
|
+
o.displayName = "FragmentsClientContext";
|
|
9
|
+
function U(r) {
|
|
10
|
+
return /* @__PURE__ */ u(o.Provider, { value: r.value, children: r.children });
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
return
|
|
12
|
+
function L() {
|
|
13
|
+
return f(o);
|
|
14
14
|
}
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const
|
|
15
|
+
const F = m(null);
|
|
16
|
+
F.displayName = "InstanceIdContext";
|
|
17
|
+
const v = m(
|
|
18
18
|
null
|
|
19
19
|
);
|
|
20
|
-
|
|
21
|
-
function
|
|
20
|
+
v.displayName = "ModulesMapContext";
|
|
21
|
+
function O({
|
|
22
22
|
value: r,
|
|
23
23
|
children: e
|
|
24
24
|
}) {
|
|
25
|
-
return /* @__PURE__ */
|
|
25
|
+
return /* @__PURE__ */ u(v.Provider, { value: r, children: e });
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
const r =
|
|
29
|
-
return
|
|
27
|
+
function W() {
|
|
28
|
+
const r = f(o);
|
|
29
|
+
return C(
|
|
30
30
|
() => ({
|
|
31
31
|
reachGoal: (e) => {
|
|
32
32
|
var n, t;
|
|
@@ -36,48 +36,72 @@ function H() {
|
|
|
36
36
|
[r]
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
|
-
function
|
|
40
|
-
const e =
|
|
39
|
+
function B(r) {
|
|
40
|
+
const e = f(v);
|
|
41
41
|
if (!e)
|
|
42
42
|
throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");
|
|
43
43
|
return e.read(r);
|
|
44
44
|
}
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const D = typeof window < "u", x = Object.freeze({
|
|
46
|
+
rootFragmentId: 0,
|
|
47
|
+
props: {},
|
|
48
|
+
projectProperties: {},
|
|
49
|
+
globalCssUrl: null
|
|
50
|
+
});
|
|
51
|
+
function V(r, e) {
|
|
52
|
+
const n = f(o);
|
|
48
53
|
if (!n)
|
|
49
54
|
throw new Error("[useArea] No FragmentsClientProvider in tree");
|
|
50
55
|
const t = n.$area;
|
|
51
56
|
if (!(t != null && t.read))
|
|
52
57
|
throw new Error("[useArea] $area plugin not mounted");
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
const l = (e == null ? void 0 : e.suspense) ?? !0, d = (e == null ? void 0 : e.pause) === !0 || !D && (e == null ? void 0 : e.ssr) === !1, s = (e == null ? void 0 : e.timeout) != null ? { timeout: e.timeout } : void 0, [, a] = I(0);
|
|
59
|
+
if (P(() => {
|
|
60
|
+
if (l || d) return;
|
|
61
|
+
let c = !0;
|
|
62
|
+
return t.resolve(r, s).finally(() => {
|
|
63
|
+
c && a((h) => h + 1);
|
|
64
|
+
}), () => {
|
|
65
|
+
c = !1;
|
|
66
|
+
};
|
|
67
|
+
}, [r, l, e == null ? void 0 : e.pause, e == null ? void 0 : e.timeout, e == null ? void 0 : e.ssr]), l)
|
|
68
|
+
return d ? x : (t.has(r) || t.resolve(r, s), t.read(r));
|
|
69
|
+
if (d)
|
|
70
|
+
return { status: "idle", data: null, error: null };
|
|
71
|
+
if (t.has(r))
|
|
72
|
+
try {
|
|
73
|
+
return { status: "ready", data: t.read(r), error: null };
|
|
74
|
+
} catch (c) {
|
|
75
|
+
return {
|
|
76
|
+
status: "not-found",
|
|
77
|
+
data: null,
|
|
78
|
+
error: c instanceof Error ? c : new Error(String(c))
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return t.resolve(r, s), { status: "loading", data: null, error: null };
|
|
58
82
|
}
|
|
59
|
-
const
|
|
60
|
-
},
|
|
61
|
-
if (!
|
|
62
|
-
return
|
|
63
|
-
const n =
|
|
83
|
+
const w = typeof window < "u", $ = () => {
|
|
84
|
+
}, i = /* @__PURE__ */ new Map(), A = (r, e) => {
|
|
85
|
+
if (!w)
|
|
86
|
+
return $;
|
|
87
|
+
const n = i.get(e);
|
|
64
88
|
if (n)
|
|
65
89
|
return n.refCount += 1, () => {
|
|
66
|
-
n.refCount -= 1, n.refCount === 0 && (n.linkEl.remove(),
|
|
90
|
+
n.refCount -= 1, n.refCount === 0 && (n.linkEl.remove(), i.delete(e));
|
|
67
91
|
};
|
|
68
92
|
const t = document.createElement("link");
|
|
69
93
|
t.rel = "stylesheet", t.href = r, t.setAttribute("data-fragment-key", e), document.head.appendChild(t);
|
|
70
|
-
const
|
|
71
|
-
return
|
|
72
|
-
|
|
94
|
+
const l = { refCount: 1, linkEl: t };
|
|
95
|
+
return i.set(e, l), () => {
|
|
96
|
+
l.refCount -= 1, l.refCount === 0 && (l.linkEl.remove(), i.delete(e));
|
|
73
97
|
};
|
|
74
|
-
},
|
|
75
|
-
function
|
|
76
|
-
|
|
98
|
+
}, T = w ? R : P;
|
|
99
|
+
function G(r, e) {
|
|
100
|
+
T(() => A(r, e), [r, e]);
|
|
77
101
|
}
|
|
78
|
-
const
|
|
79
|
-
function
|
|
80
|
-
return
|
|
102
|
+
const K = parseInt(b.split(".")[0], 10), z = K >= 19;
|
|
103
|
+
function g({ href: r, fragmentKey: e }) {
|
|
104
|
+
return z ? /* @__PURE__ */ u(
|
|
81
105
|
"link",
|
|
82
106
|
{
|
|
83
107
|
rel: "stylesheet",
|
|
@@ -85,13 +109,13 @@ function m({ href: r, fragmentKey: e }) {
|
|
|
85
109
|
precedence: "default",
|
|
86
110
|
"data-fragment-key": e
|
|
87
111
|
}
|
|
88
|
-
) : (
|
|
112
|
+
) : (G(r, e), null);
|
|
89
113
|
}
|
|
90
|
-
function
|
|
114
|
+
function X(r) {
|
|
91
115
|
}
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
class
|
|
116
|
+
const M = {}, E = m(null);
|
|
117
|
+
E.displayName = "ProjectPropertiesContext";
|
|
118
|
+
class S extends p {
|
|
95
119
|
constructor() {
|
|
96
120
|
super(...arguments), this.state = { hasError: !1 };
|
|
97
121
|
}
|
|
@@ -99,104 +123,108 @@ class y extends R {
|
|
|
99
123
|
return { hasError: !0 };
|
|
100
124
|
}
|
|
101
125
|
componentDidCatch(e, n) {
|
|
102
|
-
var t,
|
|
103
|
-
process.env.NODE_ENV !== "production" && console.error("[fragments] Area error:", e, n.componentStack), (
|
|
126
|
+
var t, l;
|
|
127
|
+
process.env.NODE_ENV !== "production" && console.error("[fragments] Area error:", e, n.componentStack), (l = (t = this.props).onError) == null || l.call(t, e);
|
|
104
128
|
}
|
|
105
129
|
render() {
|
|
106
130
|
return this.state.hasError ? null : this.props.children;
|
|
107
131
|
}
|
|
108
132
|
}
|
|
109
|
-
const
|
|
133
|
+
const j = ({
|
|
110
134
|
fragmentId: r,
|
|
111
135
|
props: e,
|
|
112
136
|
globalCssUrl: n = null,
|
|
113
|
-
projectProperties: t =
|
|
137
|
+
projectProperties: t = M
|
|
114
138
|
}) => {
|
|
115
|
-
const
|
|
116
|
-
return /* @__PURE__ */
|
|
117
|
-
n != null && /* @__PURE__ */
|
|
118
|
-
|
|
139
|
+
const l = B(r), s = L().$fragments, a = s == null ? void 0 : s.getRef(r), c = s == null ? void 0 : s.getScopeClass(r), h = e ?? {};
|
|
140
|
+
return /* @__PURE__ */ N(k, { children: [
|
|
141
|
+
n != null && /* @__PURE__ */ u(
|
|
142
|
+
g,
|
|
119
143
|
{
|
|
120
144
|
href: n,
|
|
121
145
|
fragmentKey: "global"
|
|
122
146
|
}
|
|
123
147
|
),
|
|
124
|
-
|
|
125
|
-
|
|
148
|
+
a && /* @__PURE__ */ u(
|
|
149
|
+
g,
|
|
126
150
|
{
|
|
127
|
-
href:
|
|
151
|
+
href: a.cssUrl,
|
|
128
152
|
fragmentKey: `fragment:${r}:css`
|
|
129
153
|
}
|
|
130
154
|
),
|
|
131
|
-
(
|
|
132
|
-
|
|
155
|
+
(a == null ? void 0 : a.fontsUrl) != null && /* @__PURE__ */ u(
|
|
156
|
+
g,
|
|
133
157
|
{
|
|
134
|
-
href:
|
|
158
|
+
href: a.fontsUrl,
|
|
135
159
|
fragmentKey: `fragment:${r}:fonts`
|
|
136
160
|
}
|
|
137
161
|
),
|
|
138
|
-
/* @__PURE__ */
|
|
162
|
+
/* @__PURE__ */ u(E.Provider, { value: t, children: /* @__PURE__ */ u(F.Provider, { value: null, children: /* @__PURE__ */ u(
|
|
139
163
|
"div",
|
|
140
164
|
{
|
|
141
|
-
className:
|
|
165
|
+
className: c,
|
|
142
166
|
style: { display: "contents" },
|
|
143
|
-
children: /* @__PURE__ */
|
|
167
|
+
children: /* @__PURE__ */ u(l, { ...h })
|
|
144
168
|
}
|
|
145
169
|
) }) })
|
|
146
170
|
] });
|
|
147
|
-
},
|
|
171
|
+
}, Y = ({ onError: r, ...e }) => /* @__PURE__ */ u(y, { fallback: null, children: /* @__PURE__ */ u(S, { onError: r, children: /* @__PURE__ */ u(j, { ...e }) }) }), J = ({ areaCode: r, options: e }) => {
|
|
148
172
|
if ((e == null ? void 0 : e.pause) === !0)
|
|
149
173
|
return null;
|
|
150
|
-
const
|
|
174
|
+
const n = V(r, {
|
|
151
175
|
timeout: e == null ? void 0 : e.timeout,
|
|
152
176
|
ssr: e == null ? void 0 : e.ssr
|
|
153
177
|
});
|
|
154
|
-
|
|
155
|
-
|
|
178
|
+
if (n === x)
|
|
179
|
+
return null;
|
|
180
|
+
const { rootFragmentId: t, props: l, projectProperties: d, globalCssUrl: s } = n, a = typeof (e == null ? void 0 : e.props) == "function" ? e.props(l) : e != null && e.props ? { ...l, ...e.props } : l;
|
|
181
|
+
return /* @__PURE__ */ u(
|
|
182
|
+
j,
|
|
156
183
|
{
|
|
157
|
-
fragmentId:
|
|
158
|
-
props:
|
|
159
|
-
globalCssUrl:
|
|
160
|
-
projectProperties:
|
|
184
|
+
fragmentId: t,
|
|
185
|
+
props: a,
|
|
186
|
+
globalCssUrl: s,
|
|
187
|
+
projectProperties: d
|
|
161
188
|
}
|
|
162
189
|
);
|
|
163
|
-
},
|
|
164
|
-
function
|
|
165
|
-
const n =
|
|
190
|
+
}, Z = ({ areaCode: r, options: e }) => /* @__PURE__ */ u(y, { fallback: (e == null ? void 0 : e.fallback) ?? null, children: /* @__PURE__ */ u(S, { onError: e == null ? void 0 : e.onError, children: /* @__PURE__ */ u(J, { areaCode: r, options: e }) }) });
|
|
191
|
+
function ee({ client: r, children: e }) {
|
|
192
|
+
const n = C(
|
|
166
193
|
() => ({
|
|
167
194
|
read: (t) => r.$fragments.read(t)
|
|
168
195
|
}),
|
|
169
196
|
[r]
|
|
170
197
|
);
|
|
171
|
-
return /* @__PURE__ */
|
|
198
|
+
return /* @__PURE__ */ u(U, { value: r, children: /* @__PURE__ */ u(O, { value: n, children: e }) });
|
|
172
199
|
}
|
|
173
|
-
function
|
|
174
|
-
return (
|
|
200
|
+
function re(r) {
|
|
201
|
+
return (f(E) ?? M)[r];
|
|
175
202
|
}
|
|
176
|
-
function
|
|
177
|
-
return
|
|
203
|
+
function te(r) {
|
|
204
|
+
return _({ ...r, inject: A });
|
|
178
205
|
}
|
|
179
206
|
export {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
207
|
+
x as AREA_UNRESOLVED,
|
|
208
|
+
Z as Area,
|
|
209
|
+
Y as FragmentRenderer,
|
|
210
|
+
g as FragmentStylesheet,
|
|
211
|
+
le as FragmentsApiVersionError,
|
|
212
|
+
se as FragmentsAreaError,
|
|
213
|
+
o as FragmentsClientContext,
|
|
214
|
+
U as FragmentsClientProvider,
|
|
215
|
+
ae as FragmentsLoadError,
|
|
216
|
+
ee as FragmentsProvider,
|
|
217
|
+
F as InstanceIdContext,
|
|
218
|
+
v as ModulesMapContext,
|
|
219
|
+
O as ModulesMapProvider,
|
|
220
|
+
E as ProjectPropertiesContext,
|
|
221
|
+
te as createBrowserClient,
|
|
222
|
+
M as defaultProjectProperties,
|
|
223
|
+
A as injectStylesheet,
|
|
224
|
+
V as useArea,
|
|
225
|
+
X as useCssChunk,
|
|
226
|
+
B as useFragmentComponent,
|
|
227
|
+
W as useFragmentMetrics,
|
|
228
|
+
G as useFragmentStylesheet,
|
|
229
|
+
re as useProjectProperty
|
|
202
230
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(t,
|
|
1
|
+
(function(t,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):(t=typeof globalThis<"u"?globalThis:t||self,u(t.FragmentsRuntimeReact={},t.jsxRuntime,t.React,t.fragmentsClient))})(this,function(t,u,s,m){"use strict";const o=s.createContext(null);o.displayName="FragmentsClientContext";function j(r){return u.jsx(o.Provider,{value:r.value,children:r.children})}function k(){return s.useContext(o)}const P=s.createContext(null);P.displayName="InstanceIdContext";const g=s.createContext(null);g.displayName="ModulesMapContext";function M({value:r,children:e}){return u.jsx(g.Provider,{value:r,children:e})}function x(){const r=s.useContext(o);return s.useMemo(()=>({reachGoal:e=>{var l,n;(n=(l=r==null?void 0:r.$metrics)==null?void 0:l.reachGoal)==null||n.call(l,e)}}),[r])}function S(r){const e=s.useContext(g);if(!e)throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");return e.read(r)}const _=typeof window<"u",v=Object.freeze({rootFragmentId:0,props:{},projectProperties:{},globalCssUrl:null});function w(r,e){const l=s.useContext(o);if(!l)throw new Error("[useArea] No FragmentsClientProvider in tree");const n=l.$area;if(!(n!=null&&n.read))throw new Error("[useArea] $area plugin not mounted");const a=(e==null?void 0:e.suspense)??!0,i=(e==null?void 0:e.pause)===!0||!_&&(e==null?void 0:e.ssr)===!1,c=(e==null?void 0:e.timeout)!=null?{timeout:e.timeout}:void 0,[,d]=s.useState(0);if(s.useEffect(()=>{if(a||i)return;let f=!0;return n.resolve(r,c).finally(()=>{f&&d(A=>A+1)}),()=>{f=!1}},[r,a,e==null?void 0:e.pause,e==null?void 0:e.timeout,e==null?void 0:e.ssr]),a)return i?v:(n.has(r)||n.resolve(r,c),n.read(r));if(i)return{status:"idle",data:null,error:null};if(n.has(r))try{return{status:"ready",data:n.read(r),error:null}}catch(f){return{status:"not-found",data:null,error:f instanceof Error?f:new Error(String(f))}}return n.resolve(r,c),{status:"loading",data:null,error:null}}const b=typeof window<"u",L=()=>{},h=new Map,F=(r,e)=>{if(!b)return L;const l=h.get(e);if(l)return l.refCount+=1,()=>{l.refCount-=1,l.refCount===0&&(l.linkEl.remove(),h.delete(e))};const n=document.createElement("link");n.rel="stylesheet",n.href=r,n.setAttribute("data-fragment-key",e),document.head.appendChild(n);const a={refCount:1,linkEl:n};return h.set(e,a),()=>{a.refCount-=1,a.refCount===0&&(a.linkEl.remove(),h.delete(e))}},T=b?s.useLayoutEffect:s.useEffect;function I(r,e){T(()=>F(r,e),[r,e])}const U=parseInt(s.version.split(".")[0],10)>=19;function C({href:r,fragmentKey:e}){return U?u.jsx("link",{rel:"stylesheet",href:r,precedence:"default","data-fragment-key":e}):(I(r,e),null)}function V(r){}const y={},E=s.createContext(null);E.displayName="ProjectPropertiesContext";class N extends s.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,l){var n,a;process.env.NODE_ENV!=="production"&&console.error("[fragments] Area error:",e,l.componentStack),(a=(n=this.props).onError)==null||a.call(n,e)}render(){return this.state.hasError?null:this.props.children}}const O=({fragmentId:r,props:e,globalCssUrl:l=null,projectProperties:n=y})=>{const a=S(r),c=k().$fragments,d=c==null?void 0:c.getRef(r),f=c==null?void 0:c.getScopeClass(r),A=e??{};return u.jsxs(u.Fragment,{children:[l!=null&&u.jsx(C,{href:l,fragmentKey:"global"}),d&&u.jsx(C,{href:d.cssUrl,fragmentKey:`fragment:${r}:css`}),(d==null?void 0:d.fontsUrl)!=null&&u.jsx(C,{href:d.fontsUrl,fragmentKey:`fragment:${r}:fonts`}),u.jsx(E.Provider,{value:n,children:u.jsx(P.Provider,{value:null,children:u.jsx("div",{className:f,style:{display:"contents"},children:u.jsx(a,{...A})})})})]})},B=({onError:r,...e})=>u.jsx(s.Suspense,{fallback:null,children:u.jsx(N,{onError:r,children:u.jsx(O,{...e})})}),D=({areaCode:r,options:e})=>{if((e==null?void 0:e.pause)===!0)return null;const l=w(r,{timeout:e==null?void 0:e.timeout,ssr:e==null?void 0:e.ssr});if(l===v)return null;const{rootFragmentId:n,props:a,projectProperties:i,globalCssUrl:c}=l,d=typeof(e==null?void 0:e.props)=="function"?e.props(a):e!=null&&e.props?{...a,...e.props}:a;return u.jsx(O,{fragmentId:n,props:d,globalCssUrl:c,projectProperties:i})},$=({areaCode:r,options:e})=>u.jsx(s.Suspense,{fallback:(e==null?void 0:e.fallback)??null,children:u.jsx(N,{onError:e==null?void 0:e.onError,children:u.jsx(D,{areaCode:r,options:e})})});function q({client:r,children:e}){const l=s.useMemo(()=>({read:n=>r.$fragments.read(n)}),[r]);return u.jsx(j,{value:r,children:u.jsx(M,{value:l,children:e})})}function G(r){return(s.useContext(E)??y)[r]}function J(r){return m.createFragmentsClient({...r,inject:F})}Object.defineProperty(t,"FragmentsApiVersionError",{enumerable:!0,get:()=>m.FragmentsApiVersionError}),Object.defineProperty(t,"FragmentsAreaError",{enumerable:!0,get:()=>m.FragmentsAreaError}),Object.defineProperty(t,"FragmentsLoadError",{enumerable:!0,get:()=>m.FragmentsLoadError}),t.AREA_UNRESOLVED=v,t.Area=$,t.FragmentRenderer=B,t.FragmentStylesheet=C,t.FragmentsClientContext=o,t.FragmentsClientProvider=j,t.FragmentsProvider=q,t.InstanceIdContext=P,t.ModulesMapContext=g,t.ModulesMapProvider=M,t.ProjectPropertiesContext=E,t.createBrowserClient=J,t.defaultProjectProperties=y,t.injectStylesheet=F,t.useArea=w,t.useCssChunk=V,t.useFragmentComponent=S,t.useFragmentMetrics=x,t.useFragmentStylesheet=I,t.useProjectProperty=G,Object.defineProperty(t,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.
|
|
4
|
+
"version": "0.2.0-dev-20260831061037",
|
|
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.
|
|
35
|
+
"@fragmentsx/fragments-client": "0.2.0-dev-20260831061037"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@testing-library/jest-dom": "^6.6.3",
|