@fragmentsx/runtime-react 0.2.0-dev-20260928114300 → 0.2.0-dev-20260929143730

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 CHANGED
@@ -60,6 +60,32 @@ function App() {
60
60
  не передан, клиент бьётся в `window.location.origin`, что удобно при
61
61
  same-origin проксировании `/api` на публичный API площадки.
62
62
 
63
+ ## Свойства проекта от хоста
64
+
65
+ Сайт передаёт значение один раз на всё дерево, в том числе на несколько областей:
66
+
67
+ ```tsx
68
+ const [client] = useState(() => createBrowserClient({ apiToken }));
69
+
70
+ <FragmentsProvider client={client} properties={{ langSlug }}>
71
+ <Area areaCode="lang-card" />
72
+ <Area areaCode="lang-header" />
73
+ </FragmentsProvider>
74
+ ```
75
+
76
+ Сайт может перекрыть любое свойство проекта без специальной метки. Значение из студии остаётся запасным: оно видно в preview и на сайте, когда `properties` не передан либо содержит `null`/`undefined`. Смена `properties` реактивно обновляет области без перезагрузки и перемонтирования; инлайн-объект безопасен, потому что сравнение неглубокое.
77
+
78
+ Артефакт читает значение через `useProjectProperty('langSlug')` в корне, во вложенном фрагменте и в слоте. Props варианта, привязанные `$ref` к project-свойству, получают значение сайта также в корне и слотах. Для источника значение передаётся только явно:
79
+
80
+ ```tsx
81
+ const langSlug = useProjectProperty('langSlug');
82
+ const bonuses = useSource('Scores24', { target: 'getBonuses', params: { lang: langSlug } });
83
+ ```
84
+
85
+ Приоритет: `options.props` конкретной `<Area>` > `properties` провайдера > значение студии. Функциональная форма `options.props(serverProps)` получает уже подставленные значения хоста. Хост перекрывает только project-уровень: свойства и привязки area/campaign остаются прежними. Неизвестное свойство молча недоступно — сервер отдаёт только имена, которые используют фрагменты области, и не проверяет тип значения рантайм-переопределения.
86
+
87
+ Если вы строите собственную обёртку на `useArea` вместо `<Area>`, корневые `props` содержат студийные значения, а `projectBindings` несёт карту «ключ prop → имя project-свойства»; `<Area>` подставляет корень, `FragmentRenderer` — слоты. Вложенный `FragmentsProvider` без `properties` сбрасывает значения, поскольку его клиент обычно принадлежит другому проекту.
88
+
63
89
  `Area` разрешает область в non-Suspense режиме; `Suspense` остаётся только
64
90
  вокруг загрузки модулей конуса. На сервере область не резолвится, не требует
65
91
  подключённого `$area` plugin и вместо области отдаёт `options.fallback`. Под капотом:
package/dist/index.d.ts CHANGED
@@ -395,11 +395,13 @@ export { FragmentsLoadError }
395
395
  * useMemo критично — Context value identity stability (без него cache invalidation
396
396
  * на каждый render).
397
397
  */
398
- export declare function FragmentsProvider({ client, children }: FragmentsProviderProps): ReactElement;
398
+ export declare function FragmentsProvider({ client, children, properties }: FragmentsProviderProps): ReactElement;
399
399
 
400
400
  declare interface FragmentsProviderProps {
401
401
  client: FragmentsClient;
402
402
  children: ReactNode;
403
+ /** Значения свойств проекта от сайта: перекрывают студию; null/undefined не переданы. */
404
+ properties?: Readonly<Record<string, unknown>>;
403
405
  }
404
406
 
405
407
  export declare function FragmentStylesheet({ href, fragmentKey, }: FragmentStylesheetProps): ReactElement | null;
@@ -754,6 +756,7 @@ export declare interface UseAreaResult {
754
756
  * потребителю не нужна.
755
757
  */
756
758
  projectProperties: Record<string, unknown>;
759
+ projectBindings: Record<string, string>;
757
760
  /**
758
761
  * URL к глобальному baseline reset CSS ([data-key^="Text"], [data-key^="Fragment"]).
759
762
  * `null` — backend не отдал global reset; baseline применяться не будет.
package/dist/index.es.js CHANGED
@@ -1,33 +1,33 @@
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(
1
+ import { jsx as i, jsxs as oe, Fragment as le } from "react/jsx-runtime";
2
+ import * as de from "react";
3
+ import { createContext as N, useContext as g, useMemo as k, useState as w, useEffect as P, useLayoutEffect as ie, version as fe, Component as me, Suspense as G, createElement as he, useCallback as _, useRef as x, useReducer as Ee } from "react";
4
+ import { FragmentsAreaError as ge, toScopeClassName as ve, AREA_GLOBAL_CSS_KEY as ye, resolveStylesHref as Se, fragmentCssKey as Pe, createSourceCache as Ne, sourceCallKey as D, sourceTransportKey as Ae, resolveSourceRequest as Ce, runSourceFetch as ke, createFragmentsClient as Oe } from "@fragmentsx/fragments-client";
5
+ import { FragmentsApiVersionError as ar, FragmentsAreaError as cr, FragmentsLoadError as ur, createSourceCache as or } from "@fragmentsx/fragments-client";
6
+ const C = N(
7
7
  null
8
8
  );
9
- k.displayName = "FragmentsClientContext";
10
- function Ae(r) {
11
- return /* @__PURE__ */ d(k.Provider, { value: r.value, children: r.children });
9
+ C.displayName = "FragmentsClientContext";
10
+ function we(r) {
11
+ return /* @__PURE__ */ i(C.Provider, { value: r.value, children: r.children });
12
12
  }
13
- function ke() {
14
- return v(k);
13
+ function Te() {
14
+ return g(C);
15
15
  }
16
- const z = A(null);
17
- z.displayName = "InstanceIdContext";
18
- const F = A(
16
+ const J = N(null);
17
+ J.displayName = "InstanceIdContext";
18
+ const T = N(
19
19
  null
20
20
  );
21
- F.displayName = "ModulesMapContext";
22
- function Ce({
21
+ T.displayName = "ModulesMapContext";
22
+ function be({
23
23
  value: r,
24
24
  children: e
25
25
  }) {
26
- return /* @__PURE__ */ d(F.Provider, { value: r, children: e });
26
+ return /* @__PURE__ */ i(T.Provider, { value: r, children: e });
27
27
  }
28
- function Ue() {
29
- const r = v(k);
30
- return N(
28
+ function qe() {
29
+ const r = g(C);
30
+ return k(
31
31
  () => ({
32
32
  reachGoal: (e) => {
33
33
  var t, n;
@@ -37,17 +37,18 @@ function Ue() {
37
37
  [r]
38
38
  );
39
39
  }
40
- function Pe(r) {
41
- const e = v(F);
40
+ function Fe(r) {
41
+ const e = g(T);
42
42
  if (!e)
43
43
  throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");
44
44
  return e.read(r);
45
45
  }
46
- const $ = typeof window < "u", L = Object.freeze({
46
+ const L = typeof window < "u", H = Object.freeze({
47
47
  rootFragmentId: 0,
48
48
  variantId: null,
49
49
  props: {},
50
50
  projectProperties: {},
51
+ projectBindings: {},
51
52
  globalCssUrl: null,
52
53
  // Phase 105 план 105-05: пустой конус — форма возврата хука не меняется,
53
54
  // обёртка рендера (задача 3) остаётся без атрибута class на этом сентинеле.
@@ -62,94 +63,94 @@ function R(r) {
62
63
  throw new Error("[useArea] $area plugin not mounted");
63
64
  return e;
64
65
  }
65
- function Ne(r, e) {
66
- const t = v(k);
66
+ function Re(r, e) {
67
+ const t = g(C);
67
68
  if (!t)
68
69
  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(() => {
70
+ const n = (e == null ? void 0 : e.suspense) ?? !0, s = (e == null ? void 0 : e.pause) === !0 || !L && (e == null ? void 0 : e.ssr) === !1, a = (e == null ? void 0 : e.timeout) != null ? { timeout: e.timeout } : void 0, [, o] = w(0);
71
+ if (P(() => {
71
72
  if (n || s) return;
72
- const l = R(t);
73
+ const c = R(t);
73
74
  let u = !0;
74
- return Promise.resolve(l.resolve(r, a)).catch(() => {
75
+ return Promise.resolve(c.resolve(r, a)).catch(() => {
75
76
  }).finally(() => {
76
- u && i((E) => E + 1);
77
+ u && o((f) => f + 1);
77
78
  }), () => {
78
79
  u = !1;
79
80
  };
80
81
  }, [r, n, e == null ? void 0 : e.pause, e == null ? void 0 : e.timeout, e == null ? void 0 : e.ssr]), n) {
81
82
  if (s)
82
- return L;
83
- const l = R(t);
84
- if (l.has(r) || Promise.resolve(l.resolve(r, a)).catch(() => {
85
- }), !$)
83
+ return H;
84
+ const c = R(t);
85
+ if (c.has(r) || Promise.resolve(c.resolve(r, a)).catch(() => {
86
+ }), !L)
86
87
  try {
87
- return l.read(r);
88
+ return c.read(r);
88
89
  } catch (u) {
89
90
  if (u != null && typeof u.then == "function")
90
91
  throw u;
91
92
  return process.env.NODE_ENV !== "production" && console.error(
92
93
  `[useArea] Area ${r} remained unresolved on the server because its cache reached a terminal state`,
93
94
  u
94
- ), L;
95
+ ), H;
95
96
  }
96
- return l.read(r);
97
+ return c.read(r);
97
98
  }
98
99
  if (s)
99
100
  return { status: "idle", data: null, error: null };
100
- const c = R(t);
101
- if (c.has(r))
101
+ const h = R(t);
102
+ if (h.has(r))
102
103
  try {
103
- return { status: "ready", data: c.read(r), error: null };
104
- } catch (l) {
104
+ return { status: "ready", data: h.read(r), error: null };
105
+ } catch (c) {
105
106
  return {
106
107
  status: "not-found",
107
108
  data: null,
108
- error: l instanceof Error ? l : new Error(String(l))
109
+ error: c instanceof Error ? c : new Error(String(c))
109
110
  };
110
111
  }
111
- return Promise.resolve(c.resolve(r, a)).catch(() => {
112
+ return Promise.resolve(h.resolve(r, a)).catch(() => {
112
113
  }), { status: "loading", data: null, error: null };
113
114
  }
114
- const G = typeof window < "u", we = 3e3, P = /* @__PURE__ */ new Map(), Y = (r, e) => {
115
- if (!G) {
116
- const h = () => {
115
+ const q = typeof window < "u", _e = 3e3, O = /* @__PURE__ */ new Map(), Q = (r, e) => {
116
+ if (!q) {
117
+ const E = () => {
117
118
  };
118
- return h.loaded = Promise.resolve(), h;
119
+ return E.loaded = Promise.resolve(), E;
119
120
  }
120
- const t = P.get(e);
121
+ const t = O.get(e);
121
122
  if (t) {
122
123
  t.refCount += 1;
123
- const h = () => {
124
- t.refCount -= 1, t.refCount === 0 && (t.clearReadyTimer(), t.linkEl.remove(), P.delete(e));
124
+ const E = () => {
125
+ t.refCount -= 1, t.refCount === 0 && (t.clearReadyTimer(), t.linkEl.remove(), O.delete(e));
125
126
  };
126
- return h.loaded = t.loaded, h;
127
+ return E.loaded = t.loaded, E;
127
128
  }
128
129
  const n = document.createElement("link");
129
130
  n.rel = "stylesheet", n.href = r, n.setAttribute("data-fragment-key", e);
130
131
  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));
132
+ const a = new Promise((E) => {
133
+ s = E;
134
+ }), o = () => {
135
+ c(), s();
136
+ }, h = setTimeout(o, _e), c = () => clearTimeout(h);
137
+ n.addEventListener("load", o), n.addEventListener("error", o), document.head.appendChild(n);
138
+ const u = { refCount: 1, linkEl: n, loaded: a, clearReadyTimer: c };
139
+ O.set(e, u);
140
+ const f = () => {
141
+ u.refCount -= 1, u.refCount === 0 && (u.clearReadyTimer(), u.linkEl.remove(), O.delete(e));
141
142
  };
142
- return E.loaded = a, E;
143
- }, Fe = G ? se : y;
144
- function Te(r, e) {
145
- Fe(() => Y(r, e), [r, e]);
143
+ return f.loaded = a, f;
144
+ }, xe = q ? ie : P;
145
+ function je(r, e) {
146
+ xe(() => Q(r, e), [r, e]);
146
147
  }
147
- const Re = parseInt(ue.split(".")[0], 10), _e = Re >= 19;
148
- function D({
148
+ const Ie = parseInt(fe.split(".")[0], 10), Me = Ie >= 19;
149
+ function U({
149
150
  href: r,
150
151
  fragmentKey: e
151
152
  }) {
152
- return _e ? /* @__PURE__ */ d(
153
+ return Me ? /* @__PURE__ */ i(
153
154
  "link",
154
155
  {
155
156
  rel: "stylesheet",
@@ -157,48 +158,50 @@ function D({
157
158
  precedence: "default",
158
159
  "data-fragment-key": e
159
160
  }
160
- ) : (Te(r, e), null);
161
+ ) : (je(r, e), null);
161
162
  }
162
- function pe(r) {
163
+ function Qe(r) {
163
164
  }
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";
165
+ const W = Object.freeze({}), b = N(W);
166
+ b.displayName = "HostPropertiesContext";
167
+ const X = {}, j = N(null);
168
+ j.displayName = "ProjectPropertiesContext";
169
+ const Z = Object.freeze({}), I = N(Z);
170
+ I.displayName = "SourceTransportsContext";
171
+ const M = N("live");
172
+ M.displayName = "SourceNetworkContext";
170
173
  function V(r) {
171
174
  const e = r instanceof Error ? r : new Error(String(r));
172
- if (!(e instanceof de))
175
+ if (!(e instanceof ge))
173
176
  return { kind: "failed", error: e };
174
177
  const { code: t } = e;
175
178
  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 };
176
179
  }
177
- function Q(r, e, t) {
180
+ function ee(r, e, t) {
178
181
  return typeof r == "function" ? r(e, t) : r ?? null;
179
182
  }
180
- const xe = () => {
183
+ const pe = () => {
181
184
  };
182
- function U(r) {
185
+ function K(r) {
183
186
  return r instanceof Error ? r : new Error(String(r));
184
187
  }
185
- class W extends ce {
188
+ class re extends me {
186
189
  constructor() {
187
190
  super(...arguments), this.state = { hasError: !1, error: null };
188
191
  }
189
192
  static getDerivedStateFromError(e) {
190
- return { hasError: !0, error: U(e) };
193
+ return { hasError: !0, error: K(e) };
191
194
  }
192
195
  componentDidCatch(e, t) {
193
196
  var s, a;
194
- const n = U(e);
197
+ const n = K(e);
195
198
  process.env.NODE_ENV !== "production" && console.error("[fragments] Area error:", n, t.componentStack), (a = (s = this.props).onError) == null || a.call(s, n);
196
199
  }
197
200
  render() {
198
201
  if (this.state.hasError) {
199
202
  const e = { kind: "failed", error: this.state.error ?? new Error("Unknown Area error") };
200
203
  try {
201
- return Q(this.props.empty, e, this.props.retry ?? xe);
204
+ return ee(this.props.empty, e, this.props.retry ?? pe);
202
205
  } catch {
203
206
  return null;
204
207
  }
@@ -206,82 +209,104 @@ class W extends ce {
206
209
  return this.props.children;
207
210
  }
208
211
  }
209
- function X(r, e) {
210
- if (!r) return {};
211
- const t = {};
212
- for (const n of Object.keys(r))
213
- t[n] = Oe(r[n], e);
214
- return t;
212
+ function $e(r, e) {
213
+ let t;
214
+ for (const [n, s] of Object.entries(e))
215
+ s != null && (t ?? (t = { ...r }), t[n] = s);
216
+ return t ?? r;
215
217
  }
216
- function Oe(r, e) {
217
- return Array.isArray(r) ? r.map((t, n) => t === null ? null : p(t, e, n)) : p(r, e);
218
+ function Be(r, e) {
219
+ const t = Object.keys(r);
220
+ return t.length !== Object.keys(e).length ? !1 : t.every((n) => Object.prototype.hasOwnProperty.call(e, n) && Object.is(r[n], e[n]));
218
221
  }
219
- function p(r, e, t) {
222
+ const te = Object.freeze({});
223
+ function ne(r, e, t) {
220
224
  let n;
225
+ for (const [s, a] of Object.entries(e)) {
226
+ const o = t[a];
227
+ o != null && (n ?? (n = { ...r }), n[s] = o);
228
+ }
229
+ return n ?? r;
230
+ }
231
+ function se(r, e, t) {
232
+ if (!r) return {};
233
+ const n = {};
234
+ for (const s of Object.keys(r))
235
+ n[s] = De(r[s], e, t);
236
+ return n;
237
+ }
238
+ function De(r, e, t) {
239
+ return Array.isArray(r) ? r.map((n, s) => n === null ? null : z(n, e, t, s)) : z(r, e, t);
240
+ }
241
+ function z(r, e, t, n) {
242
+ let s;
221
243
  try {
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;
244
+ s = e(r.fragmentId);
245
+ } catch (o) {
246
+ if (o != null && typeof o.then == "function")
247
+ throw o;
248
+ return console.warn(`[FragmentRenderer] Slot fragment ${r.fragmentId} failed to load — rendering empty hole`, o), null;
227
249
  }
228
- const s = X(r.slots, e);
229
- return le(n, { key: t, ...r.props, ...s });
250
+ const a = se(r.slots, e, t);
251
+ return he(s, { key: n, ...ne(r.props, r.projectBindings ?? te, t), ...a });
230
252
  }
231
- const Z = ({
253
+ const ae = ({
232
254
  fragmentId: r,
233
255
  props: e,
234
256
  globalCssUrl: t = null,
235
- projectProperties: n = J,
257
+ projectProperties: n = X,
236
258
  fragments: s = [r],
237
259
  slots: a,
238
- sources: i = q,
239
- sourceNetwork: c = "live"
260
+ sources: o = Z,
261
+ sourceNetwork: h = "live"
240
262
  }) => {
241
- const l = Pe(r), u = v(F);
263
+ const c = Fe(r), u = g(T), f = g(b);
242
264
  if (!u)
243
265
  throw new Error("[FragmentRendererInner] No ModulesMapProvider in tree");
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,
266
+ const E = se(a, u.read, f), A = k(
267
+ () => $e(n, f),
268
+ [n, f]
269
+ ), l = { ...e ?? {}, ...E }, v = s.length > 0 ? s.map(ve).join(" ") : void 0;
270
+ return /* @__PURE__ */ oe(le, { children: [
271
+ t != null && /* @__PURE__ */ i(
272
+ U,
248
273
  {
249
274
  href: t,
250
- fragmentKey: fe
275
+ fragmentKey: ye
251
276
  }
252
277
  ),
253
- s.map((m) => {
254
- const g = me(m);
255
- return g ? /* @__PURE__ */ d(
256
- D,
278
+ s.map((y) => {
279
+ const m = Se(y);
280
+ return m ? /* @__PURE__ */ i(
281
+ U,
257
282
  {
258
- href: g,
259
- fragmentKey: he(m)
283
+ href: m,
284
+ fragmentKey: Pe(y)
260
285
  },
261
- m
286
+ y
262
287
  ) : null;
263
288
  }),
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(
289
+ /* @__PURE__ */ i(M.Provider, { value: h, children: /* @__PURE__ */ i(I.Provider, { value: o, children: /* @__PURE__ */ i(j.Provider, { value: A, children: /* @__PURE__ */ i(J.Provider, { value: null, children: /* @__PURE__ */ i(
265
290
  "div",
266
291
  {
267
- className: o,
292
+ className: v,
268
293
  style: { display: "contents" },
269
- children: /* @__PURE__ */ d(l, { ...h })
294
+ children: /* @__PURE__ */ i(c, { ...l })
270
295
  }
271
296
  ) }) }) }) })
272
297
  ] });
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, {
298
+ }, We = ({ onError: r, ...e }) => /* @__PURE__ */ i(G, { fallback: null, children: /* @__PURE__ */ i(re, { onError: r, children: /* @__PURE__ */ i(ae, { ...e }) }) }), Le = ({ areaCode: r, options: e, retry: t }) => {
299
+ const n = Re(r, {
275
300
  suspense: !1,
276
301
  ssr: !1,
277
302
  pause: e == null ? void 0 : e.pause,
278
303
  timeout: e == null ? void 0 : e.timeout
279
- }), s = H(null);
280
- if (y(() => {
304
+ }), s = g(b), a = x(null);
305
+ if (P(() => {
281
306
  var S;
282
307
  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(
308
+ const m = V(n.error), d = JSON.stringify([r, m.kind, m.code, m.error.message]);
309
+ a.current !== d && (a.current = d, (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
310
  `[fragments] Area resolution ${m.kind}: areaCode=${r}, code=${m.code ?? "none"}`,
286
311
  m.error
287
312
  ));
@@ -290,104 +315,108 @@ const Z = ({
290
315
  if (n.status === "idle")
291
316
  return (e == null ? void 0 : e.fallback) ?? null;
292
317
  if (n.status === "not-found")
293
- return Q(e == null ? void 0 : e.empty, V(n.error), t);
318
+ return ee(e == null ? void 0 : e.empty, V(n.error), t);
294
319
  if (n.status === "loading" || !n.data)
295
320
  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,
321
+ const { rootFragmentId: o, props: h, projectProperties: c, globalCssUrl: u, fragments: f, slots: E, sources: A, projectBindings: l } = n.data, v = ne(h, l ?? te, s), y = typeof (e == null ? void 0 : e.props) == "function" ? e.props(v) : e != null && e.props ? { ...v, ...e.props } : v;
322
+ return /* @__PURE__ */ i(G, { fallback: (e == null ? void 0 : e.fallback) ?? null, children: /* @__PURE__ */ i(
323
+ ae,
299
324
  {
300
- fragmentId: a,
301
- props: o,
302
- globalCssUrl: l,
325
+ fragmentId: o,
326
+ props: y,
327
+ globalCssUrl: u,
303
328
  projectProperties: c,
304
- fragments: u,
329
+ fragments: f,
305
330
  slots: E,
306
- sources: h
331
+ sources: A
307
332
  }
308
333
  ) });
309
- }, Ke = ({ areaCode: r, options: e }) => {
310
- const t = v(k), [n, s] = w(0), a = t == null ? void 0 : t.$area;
311
- y(() => {
334
+ }, Xe = ({ areaCode: r, options: e }) => {
335
+ const t = g(C), [n, s] = w(0), a = t == null ? void 0 : t.$area;
336
+ P(() => {
312
337
  (e == null ? void 0 : e.ssr) !== !0 || process.env.NODE_ENV === "production" || console.error(
313
338
  "[fragments] Area option `ssr` is reserved: server resolution has been removed from the runtime; existing `ssr: false` calls continue to work unchanged."
314
339
  );
315
340
  }, [e == null ? void 0 : e.ssr]);
316
- const i = _(() => {
341
+ const o = _(() => {
317
342
  a != null && a.resolve && (a.resolve(r).catch(() => {
318
- }), s((c) => c + 1));
343
+ }), s((h) => h + 1));
319
344
  }, [a, r]);
320
345
  return (
321
346
  // A retry remounts the boundary and AreaInner: a repeated failure is a new
322
347
  // 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)
348
+ /* @__PURE__ */ i(re, { onError: e == null ? void 0 : e.onError, empty: e == null ? void 0 : e.empty, retry: o, children: /* @__PURE__ */ i(Le, { areaCode: r, options: e, retry: o }) }, n)
324
349
  );
325
350
  };
326
- function He({ client: r, children: e }) {
327
- const t = N(
351
+ function He(r) {
352
+ const e = r ?? W, t = x(e);
353
+ return Be(t.current, e) || (t.current = e), t.current;
354
+ }
355
+ function Ze({ client: r, children: e, properties: t }) {
356
+ const n = k(
328
357
  () => ({
329
- read: (n) => r.$fragments.read(n)
358
+ read: (a) => r.$fragments.read(a)
330
359
  }),
331
360
  [r]
332
- );
333
- return /* @__PURE__ */ d(Ae, { value: r, children: /* @__PURE__ */ d(Ce, { value: t, children: e }) });
361
+ ), s = He(t);
362
+ return /* @__PURE__ */ i(we, { value: r, children: /* @__PURE__ */ i(be, { value: n, children: /* @__PURE__ */ i(b.Provider, { value: s, children: e }) }) });
334
363
  }
335
- function ze(r) {
336
- return (v(x) ?? J)[r];
364
+ function er(r) {
365
+ return (g(j) ?? X)[r];
337
366
  }
338
- function Ie(r, e) {
339
- const [, t] = oe((a) => a + 1, 0), n = e(), s = H(n);
340
- return s.current = n, y(() => {
367
+ function Ue(r, e) {
368
+ const [, t] = Ee((a) => a + 1, 0), n = e(), s = x(n);
369
+ return s.current = n, P(() => {
341
370
  const a = r(t);
342
371
  return Object.is(s.current, e()) || t(), a;
343
372
  }, [r, e]), n;
344
373
  }
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 };
374
+ const Y = de.useSyncExternalStore, Ve = Y || ((r, e) => Ue(r, e)), ce = "offline", Ke = () => Promise.reject(new Error(ce));
375
+ function ze(r, e) {
376
+ var $, B;
377
+ const t = Te(), [n] = w(Ne), s = (t == null ? void 0 : t.sourceCache) ?? n, a = ($ = t == null ? void 0 : t.sourceFetchers) == null ? void 0 : $[r], o = (B = t == null ? void 0 : t.sourceBaseUrls) == null ? void 0 : B[r], h = a ? "host-fetch" : "network", c = t == null ? void 0 : t.env, u = D({ source: r, target: e.target, params: e.params }), f = k(() => ({ source: r, target: e.target, params: e.params }), [u]), E = _((F) => s.subscribe(f, F), [s, f]), A = _(() => s.get(f), [s, f]), l = Ve(E, A, A), v = g(M), y = g(I), m = Ae(r, e.target), d = k(
378
+ () => v === ce ? null : Ce(y[m], f.params, o),
379
+ [v, y, m, f, o]
380
+ ), [S, p] = w(null);
381
+ return P(() => {
382
+ (l == null ? void 0 : l.status) === "ready" && S !== null && p(null);
383
+ }, [l, S]), P(() => {
384
+ d && !d.ok && l === void 0 && console.warn(`[useSource] ${m}: ${d.reason}`);
385
+ }, [m, d == null ? void 0 : d.ok, d && !d.ok ? d.reason : void 0, l === void 0]), P(() => {
386
+ if (d && !d.ok || (l == null ? void 0 : l.status) === "ready" || S === u) return;
387
+ p(u);
388
+ const F = d && d.ok ? () => ke({ url: d.url, init: d.init }, { fetcher: a, timeout: c == null ? void 0 : c.timeout }).then((ue) => (c != null && c.debug && console.info(`[useSource] loaded ${D(f)} origin=${h}`), ue)) : Ke;
389
+ s.load(f, F, h);
390
+ }, [s, f, u, l, S, d, a, h, c == null ? void 0 : c.timeout, c == null ? void 0 : c.debug]), (l == null ? void 0 : l.status) === "ready" ? { data: l.data ?? void 0, loading: !1 } : (l == null ? void 0 : l.status) === "pending" ? { data: void 0, loading: !0 } : d && !d.ok ? { data: void 0, loading: !1 } : { data: void 0, loading: S !== u };
362
391
  }
363
- const Ge = $e;
364
- function Ye(r) {
365
- return Se({ ...r, inject: Y });
392
+ const rr = ze;
393
+ function tr(r) {
394
+ return Oe({ ...r, inject: Q });
366
395
  }
367
396
  export {
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
397
+ H as AREA_UNRESOLVED,
398
+ Xe as Area,
399
+ We as FragmentRenderer,
400
+ U as FragmentStylesheet,
401
+ ar as FragmentsApiVersionError,
402
+ cr as FragmentsAreaError,
403
+ C as FragmentsClientContext,
404
+ we as FragmentsClientProvider,
405
+ ur as FragmentsLoadError,
406
+ Ze as FragmentsProvider,
407
+ J as InstanceIdContext,
408
+ T as ModulesMapContext,
409
+ be as ModulesMapProvider,
410
+ j as ProjectPropertiesContext,
411
+ tr as createBrowserClient,
412
+ or as createSourceCache,
413
+ X as defaultProjectProperties,
414
+ Q as injectStylesheet,
415
+ Re as useArea,
416
+ Qe as useCssChunk,
417
+ Fe as useFragmentComponent,
418
+ qe as useFragmentMetrics,
419
+ je as useFragmentStylesheet,
420
+ er as useProjectProperty,
421
+ rr as useSource
393
422
  };
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
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"})});
1
+ (function(a,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):(a=typeof globalThis<"u"?globalThis:a||self,l(a.FragmentsRuntimeReact={},a.jsxRuntime,a.React,a.fragmentsClient))})(this,function(a,l,s,h){"use strict";function oe(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 ae=oe(s),O=s.createContext(null);O.displayName="FragmentsClientContext";function D(r){return l.jsx(O.Provider,{value:r.value,children:r.children})}function ce(){return s.useContext(O)}const j=s.createContext(null);j.displayName="InstanceIdContext";const A=s.createContext(null);A.displayName="ModulesMapContext";function $({value:r,children:e}){return l.jsx(A.Provider,{value:r,children:e})}function le(){const r=s.useContext(O);return s.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=s.useContext(A);if(!e)throw new Error("[useFragmentComponent] No ModulesMapProvider in tree");return e.read(r)}const H=typeof window<"u",T=Object.freeze({rootFragmentId:0,variantId:null,props:{},projectProperties:{},projectBindings:{},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=s.useContext(O);if(!t)throw new Error("[useArea] No FragmentsClientProvider in tree");const n=(e==null?void 0:e.suspense)??!0,u=(e==null?void 0:e.pause)===!0||!H&&(e==null?void 0:e.ssr)===!1,o=(e==null?void 0:e.timeout)!=null?{timeout:e.timeout}:void 0,[,f]=s.useState(0);if(s.useEffect(()=>{if(n||u)return;const c=w(t);let d=!0;return Promise.resolve(c.resolve(r,o)).catch(()=>{}).finally(()=>{d&&f(E=>E+1)}),()=>{d=!1}},[r,n,e==null?void 0:e.pause,e==null?void 0:e.timeout,e==null?void 0:e.ssr]),n){if(u)return T;const c=w(t);if(c.has(r)||Promise.resolve(c.resolve(r,o)).catch(()=>{}),!H)try{return c.read(r)}catch(d){if(d!=null&&typeof d.then=="function")throw d;return process.env.NODE_ENV!=="production"&&console.error(`[useArea] Area ${r} remained unresolved on the server because its cache reached a terminal state`,d),T}return c.read(r)}if(u)return{status:"idle",data:null,error:null};const v=w(t);if(v.has(r))try{return{status:"ready",data:v.read(r),error:null}}catch(c){return{status:"not-found",data:null,error:c instanceof Error?c:new Error(String(c))}}return Promise.resolve(v.resolve(r,o)).catch(()=>{}),{status:"loading",data:null,error:null}}const V=typeof window<"u",de=3e3,F=new Map,_=(r,e)=>{if(!V){const y=()=>{};return y.loaded=Promise.resolve(),y}const t=F.get(e);if(t){t.refCount+=1;const y=()=>{t.refCount-=1,t.refCount===0&&(t.clearReadyTimer(),t.linkEl.remove(),F.delete(e))};return y.loaded=t.loaded,y}const n=document.createElement("link");n.rel="stylesheet",n.href=r,n.setAttribute("data-fragment-key",e);let u;const o=new Promise(y=>{u=y}),f=()=>{c(),u()},v=setTimeout(f,de),c=()=>clearTimeout(v);n.addEventListener("load",f),n.addEventListener("error",f),document.head.appendChild(n);const d={refCount:1,linkEl:n,loaded:o,clearReadyTimer:c};F.set(e,d);const E=()=>{d.refCount-=1,d.refCount===0&&(d.clearReadyTimer(),d.linkEl.remove(),F.delete(e))};return E.loaded=o,E},fe=V?s.useLayoutEffect:s.useEffect;function K(r,e){fe(()=>_(r,e),[r,e])}const ie=parseInt(s.version.split(".")[0],10)>=19;function M({href:r,fragmentKey:e}){return ie?l.jsx("link",{rel:"stylesheet",href:r,precedence:"default","data-fragment-key":e}):(K(r,e),null)}function me(r){}const z=Object.freeze({}),N=s.createContext(z);N.displayName="HostPropertiesContext";const I={},k=s.createContext(null);k.displayName="ProjectPropertiesContext";const Y=Object.freeze({}),x=s.createContext(Y);x.displayName="SourceTransportsContext";const p=s.createContext("live");p.displayName="SourceNetworkContext";function G(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 q(r,e,t){return typeof r=="function"?r(e,t):r??null}const Ee=()=>{};function J(r){return r instanceof Error?r:new Error(String(r))}class Q extends s.Component{constructor(){super(...arguments),this.state={hasError:!1,error:null}}static getDerivedStateFromError(e){return{hasError:!0,error:J(e)}}componentDidCatch(e,t){var u,o;const n=J(e);process.env.NODE_ENV!=="production"&&console.error("[fragments] Area error:",n,t.componentStack),(o=(u=this.props).onError)==null||o.call(u,n)}render(){if(this.state.hasError){const e={kind:"failed",error:this.state.error??new Error("Unknown Area error")};try{return q(this.props.empty,e,this.props.retry??Ee)}catch{return null}}return this.props.children}}function he(r,e){let t;for(const[n,u]of Object.entries(e))u!=null&&(t??(t={...r}),t[n]=u);return t??r}function ge(r,e){const t=Object.keys(r);return t.length!==Object.keys(e).length?!1:t.every(n=>Object.prototype.hasOwnProperty.call(e,n)&&Object.is(r[n],e[n]))}const W=Object.freeze({});function X(r,e,t){let n;for(const[u,o]of Object.entries(e)){const f=t[o];f!=null&&(n??(n={...r}),n[u]=f)}return n??r}function Z(r,e,t){if(!r)return{};const n={};for(const u of Object.keys(r))n[u]=ve(r[u],e,t);return n}function ve(r,e,t){return Array.isArray(r)?r.map((n,u)=>n===null?null:R(n,e,t,u)):R(r,e,t)}function R(r,e,t,n){let u;try{u=e(r.fragmentId)}catch(f){if(f!=null&&typeof f.then=="function")throw f;return console.warn(`[FragmentRenderer] Slot fragment ${r.fragmentId} failed to load — rendering empty hole`,f),null}const o=Z(r.slots,e,t);return s.createElement(u,{key:n,...X(r.props,r.projectBindings??W,t),...o})}const ee=({fragmentId:r,props:e,globalCssUrl:t=null,projectProperties:n=I,fragments:u=[r],slots:o,sources:f=Y,sourceNetwork:v="live"})=>{const c=L(r),d=s.useContext(A),E=s.useContext(N);if(!d)throw new Error("[FragmentRendererInner] No ModulesMapProvider in tree");const y=Z(o,d.read,E),b=s.useMemo(()=>he(n,E),[n,E]),i={...e??{},...y},S=u.length>0?u.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}),u.map(P=>{const g=h.resolveStylesHref(P);return g?l.jsx(M,{href:g,fragmentKey:h.fragmentCssKey(P)},P):null}),l.jsx(p.Provider,{value:v,children:l.jsx(x.Provider,{value:f,children:l.jsx(k.Provider,{value:b,children:l.jsx(j.Provider,{value:null,children:l.jsx("div",{className:S,style:{display:"contents"},children:l.jsx(c,{...i})})})})})})]})},ye=({onError:r,...e})=>l.jsx(s.Suspense,{fallback:null,children:l.jsx(Q,{onError:r,children:l.jsx(ee,{...e})})}),Se=({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}),u=s.useContext(N),o=s.useRef(null);if(s.useEffect(()=>{var C;if(n.status!=="not-found"||!n.error)return;const g=G(n.error),m=JSON.stringify([r,g.kind,g.code,g.error.message]);o.current!==m&&(o.current=m,(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 q(e==null?void 0:e.empty,G(n.error),t);if(n.status==="loading"||!n.data)return(e==null?void 0:e.fallback)??null;const{rootFragmentId:f,props:v,projectProperties:c,globalCssUrl:d,fragments:E,slots:y,sources:b,projectBindings:i}=n.data,S=X(v,i??W,u),P=typeof(e==null?void 0:e.props)=="function"?e.props(S):e!=null&&e.props?{...S,...e.props}:S;return l.jsx(s.Suspense,{fallback:(e==null?void 0:e.fallback)??null,children:l.jsx(ee,{fragmentId:f,props:P,globalCssUrl:d,projectProperties:c,fragments:E,slots:y,sources:b})})},Pe=({areaCode:r,options:e})=>{const t=s.useContext(O),[n,u]=s.useState(0),o=t==null?void 0:t.$area;s.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 f=s.useCallback(()=>{o!=null&&o.resolve&&(o.resolve(r).catch(()=>{}),u(v=>v+1))},[o,r]);return l.jsx(Q,{onError:e==null?void 0:e.onError,empty:e==null?void 0:e.empty,retry:f,children:l.jsx(Se,{areaCode:r,options:e,retry:f})},n)};function Ce(r){const e=r??z,t=s.useRef(e);return ge(t.current,e)||(t.current=e),t.current}function Oe({client:r,children:e,properties:t}){const n=s.useMemo(()=>({read:o=>r.$fragments.read(o)}),[r]),u=Ce(t);return l.jsx(D,{value:r,children:l.jsx($,{value:n,children:l.jsx(N.Provider,{value:u,children:e})})})}function be(r){return(s.useContext(k)??I)[r]}function Ae(r,e){const[,t]=s.useReducer(o=>o+1,0),n=e(),u=s.useRef(n);return u.current=n,s.useEffect(()=>{const o=r(t);return Object.is(u.current,e())||t(),o},[r,e]),n}const re=ae.useSyncExternalStore,Fe=re||((r,e)=>Ae(r,e)),te="offline",Ne=()=>Promise.reject(new Error(te));function ke(r,e){var se,ue;const t=ce(),[n]=s.useState(h.createSourceCache),u=(t==null?void 0:t.sourceCache)??n,o=(se=t==null?void 0:t.sourceFetchers)==null?void 0:se[r],f=(ue=t==null?void 0:t.sourceBaseUrls)==null?void 0:ue[r],v=o?"host-fetch":"network",c=t==null?void 0:t.env,d=h.sourceCallKey({source:r,target:e.target,params:e.params}),E=s.useMemo(()=>({source:r,target:e.target,params:e.params}),[d]),y=s.useCallback(B=>u.subscribe(E,B),[u,E]),b=s.useCallback(()=>u.get(E),[u,E]),i=Fe(y,b,b),S=s.useContext(p),P=s.useContext(x),g=h.sourceTransportKey(r,e.target),m=s.useMemo(()=>S===te?null:h.resolveSourceRequest(P[g],E.params,f),[S,P,g,E,f]),[C,ne]=s.useState(null);return s.useEffect(()=>{(i==null?void 0:i.status)==="ready"&&C!==null&&ne(null)},[i,C]),s.useEffect(()=>{m&&!m.ok&&i===void 0&&console.warn(`[useSource] ${g}: ${m.reason}`)},[g,m==null?void 0:m.ok,m&&!m.ok?m.reason:void 0,i===void 0]),s.useEffect(()=>{if(m&&!m.ok||(i==null?void 0:i.status)==="ready"||C===d)return;ne(d);const B=m&&m.ok?()=>h.runSourceFetch({url:m.url,init:m.init},{fetcher:o,timeout:c==null?void 0:c.timeout}).then(we=>(c!=null&&c.debug&&console.info(`[useSource] loaded ${h.sourceCallKey(E)} origin=${v}`),we)):Ne;u.load(E,B,v)},[u,E,d,i,C,m,o,v,c==null?void 0:c.timeout,c==null?void 0:c.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}:m&&!m.ok?{data:void 0,loading:!1}:{data:void 0,loading:C!==d}}const je=ke;function Te(r){return h.createFragmentsClient({...r,inject:_})}Object.defineProperty(a,"FragmentsApiVersionError",{enumerable:!0,get:()=>h.FragmentsApiVersionError}),Object.defineProperty(a,"FragmentsAreaError",{enumerable:!0,get:()=>h.FragmentsAreaError}),Object.defineProperty(a,"FragmentsLoadError",{enumerable:!0,get:()=>h.FragmentsLoadError}),Object.defineProperty(a,"createSourceCache",{enumerable:!0,get:()=>h.createSourceCache}),a.AREA_UNRESOLVED=T,a.Area=Pe,a.FragmentRenderer=ye,a.FragmentStylesheet=M,a.FragmentsClientContext=O,a.FragmentsClientProvider=D,a.FragmentsProvider=Oe,a.InstanceIdContext=j,a.ModulesMapContext=A,a.ModulesMapProvider=$,a.ProjectPropertiesContext=k,a.createBrowserClient=Te,a.defaultProjectProperties=I,a.injectStylesheet=_,a.useArea=U,a.useCssChunk=me,a.useFragmentComponent=L,a.useFragmentMetrics=le,a.useFragmentStylesheet=K,a.useProjectProperty=be,a.useSource=je,Object.defineProperty(a,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-20260928114300",
4
+ "version": "0.2.0-dev-20260929143730",
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-20260928114300"
35
+ "@fragmentsx/fragments-client": "0.2.0-dev-20260929143730"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@testing-library/jest-dom": "^6.6.3",