@ryuzaki13/react-foundation-api 1.1.10 → 1.1.12

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.
@@ -1,6 +1,7 @@
1
1
  import { ODataServiceCollectionConfig } from "./types";
2
2
  export declare const createODataCollectionBaseQueryKey: () => readonly ["odata", "collection"];
3
3
  export declare const createODataCollectionQueryKey: ({ service, target, limitedKeys, serverFilter }: ODataServiceCollectionConfig) => readonly ["odata", "collection", {
4
+ readonly version: 2;
4
5
  readonly service: string;
5
6
  readonly target: string;
6
7
  readonly limitedKeys: readonly string[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"createODataCollectionQueryKey.d.ts","sourceRoot":"","sources":["../../src/odata/createODataCollectionQueryKey.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAEvD,eAAO,MAAM,iCAAiC,wCAAsD,CAAC;AAErG,eAAO,MAAM,6BAA6B,GAAI,gDAAgD,4BAA4B;;;;;EACxB,CAAC"}
1
+ {"version":3,"file":"createODataCollectionQueryKey.d.ts","sourceRoot":"","sources":["../../src/odata/createODataCollectionQueryKey.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAUvD,eAAO,MAAM,iCAAiC,wCAAsD,CAAC;AAErG,eAAO,MAAM,6BAA6B,GAAI,gDAAgD,4BAA4B;;;;;;EAI/G,CAAC"}
@@ -14,7 +14,6 @@ export * from "./useODataEntity";
14
14
  export * from "./useODataMetadata";
15
15
  export * from "./useODataMetadataQuery";
16
16
  export * from "./useODataTableColumns";
17
- export * from "./useTextServiceQuery";
18
17
  export { odataFetch, type ODataFetchOptions } from "./odataFetch";
19
18
  export { odataCreateFn, odataDeleteFn, odataFunctionImportFn, odataQueryFn, odataReadFn, odataUpdateFn, type ODataFetchFnRequest } from "./odataFetchFn";
20
19
  export { odataCreateFnDev, odataDeleteFnDev, odataFunctionImportFnDev, odataQueryFnDev, odataReadFnDev, odataUpdateFnDev } from "./odataFetchFnDev";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/odata/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uBAAuB,CAAC;AACtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACN,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/odata/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uBAAuB,CAAC;AACtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACN,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,MAAM,mBAAmB,CAAC"}
@@ -1,17 +1,18 @@
1
- import { C as e, S as t, _ as n, a as r, b as i, c as a, d as o, f as s, g as c, h as l, i as u, l as d, m as f, n as p, o as m, p as h, r as g, s as _, t as v, u as y, v as b, w as ee, x, y as S } from "../chunks/fetch-PmN9NBra.js";
2
- import { S as te, _ as ne, a as re, b as ie, c as ae, d as oe, f as se, g as ce, h as le, i as ue, l as de, m as fe, n as pe, o as me, p as he, r as C, s as ge, t as _e, u as ve, v as w, x as T, y as ye } from "../chunks/odataFetchFn-CzhXMYXj.js";
3
- import { logError as be } from "@ryuzaki13/react-foundation-lib/utils";
4
- import { parseDate as xe } from "@ryuzaki13/react-foundation-lib/formatters";
5
- import { compareStrings as Se } from "@ryuzaki13/react-foundation-lib/string-comparison";
6
- import { useCallback as E, useEffect as Ce, useMemo as D, useRef as we, useState as O } from "react";
7
- import { queryOptions as Te, useQuery as k, useQueryClient as A } from "@tanstack/react-query";
8
- import { buildSeparatedArrays as Ee, useODataCollectionStore as De } from "@ryuzaki13/react-foundation-lib/odata";
9
- import { persistedQueryMeta as j } from "@ryuzaki13/react-foundation-lib/query-client";
10
- import { buildEntityPath as Oe } from "@ryuzaki13/react-foundation-lib/odata-service";
11
- import { createTableColumnVisibilityFromODataMetadata as M, createTableColumnsFromODataMetadata as ke, enrichTableColumnsWithODataFormatting as Ae, resolveStableColumnId as je } from "@ryuzaki13/react-foundation-lib/table";
12
- import { notify as Me } from "@ryuzaki13/react-foundation-lib/notifications";
1
+ import { C as e, S as t, _ as n, a as r, b as i, c as a, d as o, f as s, g as c, h as l, i as u, l as d, m as f, n as p, o as m, p as h, r as g, s as _, t as v, u as y, v as b, w as x, x as S, y as C } from "../chunks/fetch-PmN9NBra.js";
2
+ import { S as w, _ as ee, a as te, b as ne, c as re, d as ie, f as ae, g as oe, h as se, i as ce, l as le, m as ue, n as de, o as fe, p as pe, r as T, s as me, t as he, u as ge, v as E, x as D, y as _e } from "../chunks/odataFetchFn-CzhXMYXj.js";
3
+ import { logError as ve } from "@ryuzaki13/react-foundation-lib/utils";
4
+ import { parseDate as ye } from "@ryuzaki13/react-foundation-lib/formatters";
5
+ import { compareStrings as O } from "@ryuzaki13/react-foundation-lib/string-comparison";
6
+ import { useCallback as k, useEffect as A, useMemo as j, useRef as be, useState as M } from "react";
7
+ import { queryOptions as xe, useQuery as N, useQueryClient as P } from "@tanstack/react-query";
8
+ import { buildSeparatedArrays as Se, useODataCollectionStore as Ce } from "@ryuzaki13/react-foundation-lib/odata";
9
+ import { persistedQueryMeta as F } from "@ryuzaki13/react-foundation-lib/query-client";
10
+ import { buildEntityPath as we } from "@ryuzaki13/react-foundation-lib/odata-service";
11
+ import { createTableColumnVisibilityFromODataMetadata as I, createTableColumnsFromODataMetadata as Te, enrichTableColumnsWithODataFormatting as Ee, resolveStableColumnId as De } from "@ryuzaki13/react-foundation-lib/table";
12
+ import { notify as Oe } from "@ryuzaki13/react-foundation-lib/notifications";
13
13
  //#region src/odata/createODataCollectionQueryKey.ts
14
- var N = () => [...te, "collection"], P = ({ service: e, target: t, limitedKeys: n, serverFilter: r }) => [...N(), {
14
+ var ke = 2, L = () => [...w, "collection"], R = ({ service: e, target: t, limitedKeys: n, serverFilter: r }) => [...L(), {
15
+ version: ke,
15
16
  service: e,
16
17
  target: t,
17
18
  limitedKeys: n,
@@ -19,7 +20,7 @@ var N = () => [...te, "collection"], P = ({ service: e, target: t, limitedKeys:
19
20
  }];
20
21
  //#endregion
21
22
  //#region src/odata/flattenODataDependentServices.ts
22
- function Ne(e) {
23
+ function Ae(e) {
23
24
  let t = [];
24
25
  for (let [n, r] of e.entries()) {
25
26
  let e = `${r.odata.service}.${r.odata.target}`;
@@ -41,7 +42,7 @@ function Ne(e) {
41
42
  }
42
43
  //#endregion
43
44
  //#region src/odata/sortODataDependentSegmentItemsByChains.ts
44
- function Pe(e, t, n) {
45
+ function je(e, t, n) {
45
46
  let r = /* @__PURE__ */ new Map();
46
47
  for (let [e, n] of Object.entries(t)) r.set(e, new Map(n.map((e, t) => [e.codeKey, t])));
47
48
  let i = [...e].map((e, t) => ({
@@ -63,7 +64,7 @@ function Pe(e, t, n) {
63
64
  }
64
65
  //#endregion
65
66
  //#region src/odata/sortODataDependentServicesByChains.ts
66
- function Fe(e, t) {
67
+ function Me(e, t) {
67
68
  if (!t?.length) return [...e];
68
69
  let n = /* @__PURE__ */ new Set();
69
70
  for (let t of e) for (let e of Object.keys(t.segments)) n.add(e);
@@ -82,13 +83,13 @@ function Fe(e, t) {
82
83
  return (n ? o.get(n) ?? 2 ** 53 - 1 : 2 ** 53 - 1) - (r ? o.get(r) ?? 2 ** 53 - 1 : 2 ** 53 - 1);
83
84
  });
84
85
  }
85
- function Ie(e, t, n) {
86
- return Fe(e.map((e) => {
86
+ function Ne(e, t, n) {
87
+ return Me(e.map((e) => {
87
88
  let n = t[`${e.odata.service}.${e.odata.target}`];
88
89
  if (!n?.length) return e;
89
90
  let r = new Map(n.map((e, t) => [e.codeKey, t])), i = Object.entries(e.segments).sort(([e], [t]) => {
90
91
  let n = r.get(e), i = r.get(t);
91
- return n !== void 0 && i !== void 0 ? n - i : n === void 0 ? i === void 0 ? Se(e, t) : 1 : -1;
92
+ return n !== void 0 && i !== void 0 ? n - i : n === void 0 ? i === void 0 ? O(e, t) : 1 : -1;
92
93
  });
93
94
  return {
94
95
  ...e,
@@ -98,61 +99,73 @@ function Ie(e, t, n) {
98
99
  }
99
100
  //#endregion
100
101
  //#region src/odata/fetchCollectionData.ts
101
- async function Le(e) {
102
+ async function Pe(e) {
102
103
  let { url: t, query: n, signal: r } = e;
103
104
  try {
104
- let e = await T(t, n, { signal: r });
105
+ let e = await D(t, n, { signal: r });
105
106
  if (a(e)) throw Error("отсутствует тело ответа");
106
107
  return { items: e.data.map(({ ID: e, CNT: t, __metadata: n, __Parameters: r, ...i }) => i) };
107
108
  } catch (e) {
108
- return be("Ошибка загрузки справочника:", e), { items: [] };
109
+ return ve("Ошибка загрузки справочника:", e), { items: [] };
109
110
  }
110
111
  }
111
112
  //#endregion
113
+ //#region src/odata/projectODataCollectionSort.ts
114
+ function Fe(e) {
115
+ let t = !1, n = Object.fromEntries(Object.entries(e.separated).map(([n, r]) => {
116
+ let i = e.keyPairsMap[n];
117
+ return !i || r.length < 2 ? [n, r] : (t = !0, [n, [...r].sort((e, t) => O(String(e[i] ?? ""), String(t[i] ?? "")))]);
118
+ }));
119
+ return t ? {
120
+ ...e,
121
+ separated: n
122
+ } : e;
123
+ }
124
+ //#endregion
112
125
  //#region src/odata/useODataCollectionUpdatesQuery.ts
113
- var Re = __APP_BUILD_ID__, ze = 1e3 * 60 * 60 * 4, F = 1e3 * 60 * 60 * 24 * 7, I = "ttl=forever;name=ref", L = "bust=forever;name=ref", R = "ttl=4h;name=ref-updates", z = () => [
114
- ...te,
126
+ var Ie = __APP_BUILD_ID__, Le = 1e3 * 60 * 60 * 4, z = 1e3 * 60 * 60 * 24 * 7, B = "ttl=forever;name=ref", V = "bust=forever;name=ref", H = "ttl=4h;name=ref-updates", U = () => [
127
+ ...w,
115
128
  "collection-updates",
116
- { buildId: Re }
129
+ { buildId: Ie }
117
130
  ];
118
- function Be(e) {
131
+ function Re(e) {
119
132
  return {
120
133
  ...e,
121
- lastChangedAt: xe(e.lastChanged)
134
+ lastChangedAt: ye(e.lastChanged)
122
135
  };
123
136
  }
124
- function B(e, t) {
125
- let n = e.map(Be);
137
+ function W(e, t) {
138
+ let n = e.map(Re);
126
139
  return {
127
140
  items: n,
128
141
  byEntityName: n.reduce((e, t) => (t.entityName && (e[t.entityName] = t), e), {}),
129
142
  fetchedAt: t,
130
- coverageStartedAt: t - F
143
+ coverageStartedAt: t - z
131
144
  };
132
145
  }
133
- function V() {
146
+ function G() {
134
147
  return async ({ signal: t }) => {
135
- let n = Date.now(), r = x().collectionUpdates;
136
- return r ? B((await T(`/${r.service}/${r.target}`, {
148
+ let n = Date.now(), r = S().collectionUpdates;
149
+ return r ? W((await D(`/${r.service}/${r.target}`, {
137
150
  baseUrl: e(r.service, r.baseUrl),
138
- swCache: R
139
- }, { signal: t })).data, Math.max(n, Date.now())) : B([], n);
151
+ swCache: H
152
+ }, { signal: t })).data, Math.max(n, Date.now())) : W([], n);
140
153
  };
141
154
  }
142
- var H = (e = {}) => Te({
143
- queryKey: z(),
144
- queryFn: V(),
145
- meta: j,
146
- staleTime: e.staleTime ?? ze,
155
+ var ze = (e = {}) => xe({
156
+ queryKey: U(),
157
+ queryFn: G(),
158
+ meta: F,
159
+ staleTime: e.staleTime ?? Le,
147
160
  gcTime: Infinity
148
161
  });
149
- function U(e = {}) {
150
- return k(H(e));
162
+ function Be(e = {}) {
163
+ return N(ze(e));
151
164
  }
152
165
  //#endregion
153
166
  //#region src/odata/useODataMetadata.ts
154
- function W(e) {
155
- let { data: t, dataUpdatedAt: n = 0, isLoading: r, isLoadingError: i } = w({ service: e.service }), a = t?.entities[e.target];
167
+ function K(e) {
168
+ let { data: t, dataUpdatedAt: n = 0, isLoading: r, isLoadingError: i } = E({ service: e.service }), a = t?.entities[e.target];
156
169
  if (!r && !a && t?.functionImports[e.target]) throw Error(`OData target '${e.target}' является FunctionImport и не может использоваться как сущность`);
157
170
  if (i) throw Error(`Ошибка загрузки метаданных сервиса ${e.service}`);
158
171
  return {
@@ -163,32 +176,32 @@ function W(e) {
163
176
  }
164
177
  //#endregion
165
178
  //#region src/odata/useODataEntity.ts
166
- var G = "Использование actions недопустимо до окончания загрузки metadata";
167
- function K(e) {
168
- let { metadata: t, metadataUpdatedAt: n, isLoading: r } = W(e);
179
+ var q = "Использование actions недопустимо до окончания загрузки metadata";
180
+ function Ve(e) {
181
+ let { metadata: t, metadataUpdatedAt: n, isLoading: r } = K(e);
169
182
  return {
170
183
  config: e,
171
184
  metadata: t,
172
185
  metadataUpdatedAt: n,
173
186
  isLoading: r,
174
- actions: D(() => ({
187
+ actions: j(() => ({
175
188
  getEntityPath: (n = {}) => {
176
- if (!t) throw Error(G);
177
- return Oe(t, e, n);
189
+ if (!t) throw Error(q);
190
+ return we(t, e, n);
178
191
  },
179
192
  getKeys: () => {
180
- if (!t) throw Error(G);
193
+ if (!t) throw Error(q);
181
194
  return t.columns?.map((e) => e.id);
182
195
  },
183
196
  getKeyPairs: () => {
184
- if (!t) throw Error(G);
197
+ if (!t) throw Error(q);
185
198
  return t.columns?.filter((e) => e.semanticType === "code" && e.linkedColumnId).map((e) => ({
186
199
  codeKey: e.id,
187
200
  textKey: e.linkedColumnId
188
201
  }));
189
202
  },
190
203
  getKeyPairsMap: () => {
191
- if (!t) throw Error(G);
204
+ if (!t) throw Error(q);
192
205
  let e = {};
193
206
  for (let n of t.columns ?? []) n.semanticType === "code" && n.linkedColumnId && (e[n.id] = n.linkedColumnId);
194
207
  return e;
@@ -198,20 +211,20 @@ function K(e) {
198
211
  }
199
212
  //#endregion
200
213
  //#region src/odata/useODataCollectionQuery.ts
201
- function q(e, t) {
214
+ function He(e, t) {
202
215
  if (!t) return e;
203
216
  let n = e.trim().toLowerCase();
204
- return n === "off" || n.startsWith("bust=") ? e : n.startsWith("ttl=") ? e.replace(/^\s*ttl=/i, "bust=") : L;
217
+ return n === "off" || n.startsWith("bust=") ? e : n.startsWith("ttl=") ? e.replace(/^\s*ttl=/i, "bust=") : V;
205
218
  }
206
219
  function J(e) {
207
220
  return typeof e == "number" && Number.isFinite(e) && e > 0;
208
221
  }
209
- function Y(e, t) {
222
+ function Ue(e, t) {
210
223
  let n = t?.cacheUpdatedAt ?? 0, r = e.update?.lastChangedAt?.getTime();
211
224
  return !!(J(r) && (!t || !n || r > n) || J(e.metadataUpdatedAt) && (!t || !n || e.metadataUpdatedAt > n) || J(e.updatesCoverageStartedAt) && (!t || !n || n < e.updatesCoverageStartedAt));
212
225
  }
213
- function X(e) {
214
- let { service: t, target: n, limitedKeys: r, excludeEmpty: i, sortByCode: a, serverFilter: o, clientFilter: s, swCache: c = I } = e, l = A(), { actions: u, metadata: d, metadataUpdatedAt: f, isLoading: p } = K(e), m = U(), h = D(() => P({
226
+ function We(e) {
227
+ let { service: t, target: n, limitedKeys: r, excludeEmpty: i, sortByCode: a, serverFilter: o, clientFilter: s, swCache: c = B } = e, l = P(), { actions: u, metadata: d, metadataUpdatedAt: f, isLoading: p } = Ve(e), m = Be(), h = j(() => R({
215
228
  service: t,
216
229
  target: n,
217
230
  limitedKeys: r,
@@ -221,60 +234,61 @@ function X(e) {
221
234
  n,
222
235
  r,
223
236
  o
224
- ]), g = l.getQueryData(h), _ = m.data?.byEntityName[n], v = Y({
237
+ ]), g = l.getQueryData(h), _ = m.data?.byEntityName[n], v = Ue({
225
238
  update: _,
226
239
  metadataUpdatedAt: f,
227
240
  updatesCoverageStartedAt: m.data?.coverageStartedAt
228
- }, g), y = q(c, v), b = m.isError || m.isSuccess && !m.isFetching;
229
- return Ce(() => {
241
+ }, g), y = He(c, v), b = m.isError || m.isSuccess && !m.isFetching;
242
+ return A(() => {
230
243
  !g || !v || l.invalidateQueries({ queryKey: h });
231
244
  }, [
232
245
  g,
233
246
  l,
234
247
  h,
235
248
  v
236
- ]), k({
249
+ ]), N({
237
250
  queryKey: h,
238
251
  queryFn: async ({ signal: e }) => {
239
- let c = Date.now(), l = r ? [...r] : u.getKeys(), d = u.getKeyPairs(), p = u.getKeyPairsMap();
252
+ let a = Date.now(), c = r ? [...r] : u.getKeys(), l = u.getKeyPairs(), d = u.getKeyPairsMap();
240
253
  if (r) for (let e of r) {
241
- let t = p[e];
242
- t && !l.includes(t) && l.push(t);
254
+ let t = d[e];
255
+ t && !c.includes(t) && c.push(t);
243
256
  }
244
- let { items: m } = await Le({
257
+ let { items: p } = await Pe({
245
258
  url: `/${t}/${n}`,
246
259
  query: {
247
- select: l,
260
+ select: c,
248
261
  expression: o,
249
262
  swCache: y
250
263
  },
251
264
  signal: e
252
- }), h = m;
253
- s && (h = m.filter(s));
254
- let g = Ee(h, d, i, a), v = d.map((e) => ({
265
+ }), m = p;
266
+ s && (m = p.filter(s));
267
+ let h = Se(m, l, i, !0), g = l.map((e) => ({
255
268
  codeKey: e.codeKey,
256
- count: g[e.codeKey].length
269
+ count: h[e.codeKey].length
257
270
  })).sort((e, t) => e.count - t.count);
258
271
  return {
259
- items: h,
260
- keyPairs: d,
261
- keyPairsMap: p,
262
- separated: g,
263
- chain: v,
264
- count: h.length,
265
- cacheUpdatedAt: Math.max(c, Date.now(), _?.lastChangedAt?.getTime() ?? 0, f)
272
+ items: m,
273
+ keyPairs: l,
274
+ keyPairsMap: d,
275
+ separated: h,
276
+ chain: g,
277
+ count: m.length,
278
+ cacheUpdatedAt: Math.max(a, Date.now(), _?.lastChangedAt?.getTime() ?? 0, f)
266
279
  };
267
280
  },
268
281
  enabled: !!(!p && d && t && n && b),
269
- meta: j,
282
+ meta: F,
270
283
  staleTime: 1e3 * 60 * 60 * 2,
271
- gcTime: 1e3 * 60 * 60 * 1
284
+ gcTime: 1e3 * 60 * 60 * 1,
285
+ select: a === !1 ? Fe : void 0
272
286
  });
273
287
  }
274
288
  //#endregion
275
289
  //#region src/odata/useODataCollection.ts
276
- function Ve({ odata: e, model: t, pageSize: n = 50 }) {
277
- let { codeKey: r, maxVisibleItems: i } = t, { data: a, isLoading: o, isError: s, refetch: c } = X(e), l = a?.keyPairsMap[r] ?? "", u = A(), [d, f] = O(), p = we(/* @__PURE__ */ new Map()), { itemsMap: m, separatedItems: h, orderedKeys: g } = D(() => {
290
+ function Ge({ odata: e, model: t, pageSize: n = 50 }) {
291
+ let { codeKey: r, maxVisibleItems: i } = t, { data: a, isLoading: o, isError: s, refetch: c } = We(e), l = a?.keyPairsMap[r] ?? "", u = P(), [d, f] = M(), p = be(/* @__PURE__ */ new Map()), { itemsMap: m, separatedItems: h, orderedKeys: g } = j(() => {
278
292
  let e = /* @__PURE__ */ new Map(), t = [], n = [];
279
293
  if (a && a.separated[r]) {
280
294
  n = a.separated[r];
@@ -288,7 +302,7 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
288
302
  separatedItems: n,
289
303
  orderedKeys: t
290
304
  };
291
- }, [a, r]), _ = E((e) => {
305
+ }, [a, r]), _ = k((e) => {
292
306
  let t = a?.separated[r];
293
307
  if (!t) return /* @__PURE__ */ new Map();
294
308
  let n = /* @__PURE__ */ new Map();
@@ -300,11 +314,11 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
300
314
  }
301
315
  }
302
316
  return n;
303
- }, [a, r]), v = E((e) => {
317
+ }, [a, r]), v = k((e) => {
304
318
  f(() => {
305
319
  if (e?.length) return new Set(e.map((e) => e[r]));
306
320
  });
307
- }, [r]), y = E((e, t) => {
321
+ }, [r]), y = k((e, t) => {
308
322
  if (!g.length) return [];
309
323
  let n = i, a = /* @__PURE__ */ new Set(), o = [];
310
324
  if (t?.length) for (let e = 0; e < t.length; e++) a.add(t[e][r]);
@@ -324,57 +338,57 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
324
338
  m,
325
339
  d,
326
340
  l
327
- ]), b = E((e) => {
341
+ ]), b = k((e) => {
328
342
  let t = a?.separated[r] || [], i = e * n, o = i + n;
329
343
  return t.slice(i, o);
330
344
  }, [
331
345
  a,
332
346
  n,
333
347
  r
334
- ]), ee = E((e, t) => {
348
+ ]), x = k((e, t) => {
335
349
  if (!a) return [];
336
350
  let n = new Set(t);
337
351
  return a.items.filter((t) => n.has(t[e]));
338
- }, [a]), x = E((e, t, n = 200) => {
352
+ }, [a]), S = k((e, t, n = 200) => {
339
353
  p.current.has(e) && clearTimeout(p.current.get(e));
340
354
  let r = setTimeout(t, n);
341
355
  p.current.set(e, r);
342
- }, []), S = E(() => {
356
+ }, []), C = k(() => {
343
357
  for (let e of p.current.values()) clearTimeout(e);
344
358
  p.current.clear();
345
359
  }, []);
346
- return D(() => () => {
347
- S();
348
- }, [S]), {
360
+ return j(() => () => {
361
+ C();
362
+ }, [C]), {
349
363
  data: a,
350
364
  isLoading: o,
351
365
  isError: s,
352
366
  codeKey: r,
353
367
  textKey: l,
354
368
  getItems: y,
355
- findSourceItemsByKeys: ee,
369
+ findSourceItemsByKeys: x,
356
370
  setFilteredItems: v,
357
371
  getPage: b,
358
372
  buildSearchIndex: _,
359
- debounce: x,
373
+ debounce: S,
360
374
  itemsMap: m,
361
375
  separatedItems: h,
362
376
  orderedKeys: g,
363
377
  refetch: c,
364
- invalidate: () => u.invalidateQueries({ queryKey: P(e) }),
378
+ invalidate: () => u.invalidateQueries({ queryKey: R(e) }),
365
379
  totalCount: a?.separated[r]?.length || 0,
366
380
  pageSize: n
367
381
  };
368
382
  }
369
383
  //#endregion
370
384
  //#region src/odata/useODataCollectionChains.ts
371
- function He(e) {
372
- let t = A(), [n, r] = O({}), i = D(() => e.map((e) => P(e)), [e]);
373
- return Ce(() => {
385
+ function Ke(e) {
386
+ let t = P(), [n, r] = M({}), i = j(() => e.map((e) => R(e)), [e]);
387
+ return A(() => {
374
388
  function n() {
375
389
  let n = {};
376
390
  for (let r of e) {
377
- let e = P(r), i = t.getQueryData(e);
391
+ let e = R(r), i = t.getQueryData(e);
378
392
  i?.chain && (n[`${r.service}.${r.target}`] = i.chain);
379
393
  }
380
394
  r((e) => Object.keys(e).length === Object.keys(n).length && Object.entries(n).every(([t, n]) => e[t] === n) ? e : n);
@@ -393,9 +407,9 @@ function He(e) {
393
407
  }
394
408
  //#endregion
395
409
  //#region src/odata/useODataCollectionModel.ts
396
- function Ue(e) {
397
- let [t] = O(() => {
398
- let t = De.getState(), { codeKey: n, maxVisibleItems: r = t.defaultMaxVisibleItems, minSearchCodeLength: i = t.defaultMinSearchCodeLength, minSearchTextLength: a = t.defaultMinSearchTextLength, searchDebounceDelay: o = t.defaultSearchDebounceDelay } = e;
410
+ function qe(e) {
411
+ let [t] = M(() => {
412
+ let t = Ce.getState(), { codeKey: n, maxVisibleItems: r = t.defaultMaxVisibleItems, minSearchCodeLength: i = t.defaultMinSearchCodeLength, minSearchTextLength: a = t.defaultMinSearchTextLength, searchDebounceDelay: o = t.defaultSearchDebounceDelay } = e;
399
413
  return {
400
414
  codeKey: n,
401
415
  maxVisibleItems: r,
@@ -408,56 +422,48 @@ function Ue(e) {
408
422
  }
409
423
  //#endregion
410
424
  //#region src/odata/useODataTableColumns.ts
411
- function We(e, t) {
425
+ function Je(e, t) {
412
426
  let n = {}, r = (e) => {
413
427
  for (let i of e) {
414
428
  if ("columns" in i && Array.isArray(i.columns) && i.columns.length > 0) {
415
429
  r(i.columns);
416
430
  continue;
417
431
  }
418
- let e = je(i);
432
+ let e = De(i);
419
433
  !e || !(e in t) || (n[e] = t[e]);
420
434
  }
421
435
  };
422
436
  return r(e), n;
423
437
  }
424
- function Ge(e) {
425
- let { metadata: t, isLoading: n } = W(e);
438
+ function Ye(e) {
439
+ let { metadata: t, isLoading: n } = K(e);
426
440
  return {
427
- columns: D(() => t ? e.mode === "build" ? ke(t.columns, {
441
+ columns: j(() => t ? e.mode === "build" ? Te(t.columns, {
428
442
  resolveHeader: e.resolveHeader,
429
443
  resolveFormatting: e.resolveFormatting
430
- }) : Ae(e.columns, t.columns) : e.mode === "build" ? [] : [...e.columns], [e, t]),
431
- defaultColumnVisibility: D(() => {
444
+ }) : Ee(e.columns, t.columns) : e.mode === "build" ? [] : [...e.columns], [e, t]),
445
+ defaultColumnVisibility: j(() => {
432
446
  if (!t) return;
433
- if (e.mode === "build") return M(t.columns, { resolveVisible: e.resolveVisible });
434
- let n = M(t.columns);
435
- return We(e.columns, n);
447
+ if (e.mode === "build") return I(t.columns, { resolveVisible: e.resolveVisible });
448
+ let n = I(t.columns);
449
+ return Je(e.columns, n);
436
450
  }, [e, t]),
437
451
  metadata: t,
438
452
  isLoading: n
439
453
  };
440
454
  }
441
455
  //#endregion
442
- //#region src/odata/useTextServiceQuery.ts
443
- function Ke(e) {
444
- return X({
445
- service: "TEXT_DICTIONARY_SRV",
446
- target: e
447
- });
448
- }
449
- //#endregion
450
456
  //#region src/odata/odataFetchFnDev.ts
451
- function qe() {
457
+ function Xe() {
452
458
  return globalThis.console;
453
459
  }
454
- function Je(e) {
460
+ function Y(e) {
455
461
  let t = {};
456
462
  return new Headers(e).forEach((e, n) => {
457
463
  t[n] = e;
458
464
  }), t;
459
465
  }
460
- function Ye(e) {
466
+ function Ze(e) {
461
467
  if (e != null) {
462
468
  if (typeof e != "string") return e;
463
469
  try {
@@ -467,32 +473,32 @@ function Ye(e) {
467
473
  }
468
474
  }
469
475
  }
470
- function Xe(e) {
476
+ function X(e) {
471
477
  return e !== void 0 && !["GET", "HEAD"].includes(e.toUpperCase());
472
478
  }
473
- function Ze(e) {
479
+ function Qe(e) {
474
480
  return (e.baseUrl ?? "odata") !== "" || e.path.startsWith("/sap/") || e.path.startsWith("/sap-dp0/");
475
481
  }
476
- function Qe(e, t) {
482
+ function $e(e, t) {
477
483
  let n = t.toLowerCase();
478
484
  return Object.keys(e).some((e) => e.toLowerCase() === n);
479
485
  }
480
486
  function Z(e, t, n) {
481
- Qe(e, t) || (e[t] = n);
482
- }
483
- function $e(e) {
484
- let t = Je(e.init.headers), n = e.init.method, r = Ze(e);
485
- return Z(t, "DataServiceVersion", "2.0"), Z(t, "MaxDataServiceVersion", "2.0"), Z(t, "Accept", "application/json"), t["sap-language"] = "ru", r && (t["sap-contextid-accept"] = "header"), Xe(n) && e.init.body && Z(t, "Content-Type", "application/json"), Xe(n) && r && Z(t, "x-csrf-token", "<получается отдельным GET перед реальным write-запросом>"), t;
487
+ $e(e, t) || (e[t] = n);
486
488
  }
487
489
  function et(e) {
488
- return de(e) ? "FunctionImport" : e.result ? "Parameterized Entity" : "Entity";
490
+ let t = Y(e.init.headers), n = e.init.method, r = Qe(e);
491
+ return Z(t, "DataServiceVersion", "2.0"), Z(t, "MaxDataServiceVersion", "2.0"), Z(t, "Accept", "application/json"), t["sap-language"] = "ru", r && (t["sap-contextid-accept"] = "header"), X(n) && e.init.body && Z(t, "Content-Type", "application/json"), X(n) && r && Z(t, "x-csrf-token", "<получается отдельным GET перед реальным write-запросом>"), t;
492
+ }
493
+ function tt(e) {
494
+ return le(e) ? "FunctionImport" : e.result ? "Parameterized Entity" : "Entity";
489
495
  }
490
496
  function Q(e, t) {
491
- let n = qe();
497
+ let n = Xe();
492
498
  n.groupCollapsed(e), n.info(t), n.groupEnd();
493
499
  }
494
- function tt(e) {
495
- let t = qe(), n = Ye(e.request.init.body), r = Je(e.request.init.headers), i = $e(e.request), a = {
500
+ function nt(e) {
501
+ let t = Xe(), n = Ze(e.request.init.body), r = Y(e.request.init.headers), i = et(e.request), a = {
496
502
  method: e.request.init.method,
497
503
  headers: r,
498
504
  body: n,
@@ -502,7 +508,7 @@ function tt(e) {
502
508
  helper: e.helperName,
503
509
  operation: e.operation,
504
510
  target: e.odata.target,
505
- targetKind: et(e.target),
511
+ targetKind: tt(e.target),
506
512
  service: e.odata.service,
507
513
  realFetch: "не выполнялся"
508
514
  }]), t.info("Итоговый URL:", e.request.fullUrl), t.info("Path без base URL:", e.request.path), t.info("Target path до query options:", e.targetPath), t.info("Query string:", e.request.queryString || "<пусто>"), t.info("Body:", n ?? "<пусто>"), t.info("Auto parse:", e.autoParse ?? !1), t.info("Transform:", e.hasTransform ? "передан, но не вызывается без ответа backend" : "не передан"), t.info("Dry-run result:", e.operation === "query" ? {
@@ -510,34 +516,34 @@ function tt(e) {
510
516
  totalCount: 0
511
517
  } : { data: void 0 }), Q("OData config", e.odata), Q("Target metadata", e.target), Q("Target params", e.params), Q("Query options", e.queryOptions), Q("RequestInit, переданный в transport", a), Q("Заголовки после transport defaults (без реального fetch)", i), t.groupEnd();
512
518
  }
513
- function nt(e) {
514
- Me.warning(`${e}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, { title: "OData DEV helper" });
519
+ function rt(e) {
520
+ Oe.warning(`${e}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, { title: "OData DEV helper" });
515
521
  }
516
522
  function $(t, n, r) {
517
523
  let { odata: i, options: a = {}, init: o = {}, autoParse: s, swCache: c } = n, l = n.params ?? {};
518
524
  return async ({ client: u, signal: d }) => {
519
- nt(r);
520
- let f = e(i.service, a.baseUrl), p = await ce({
525
+ rt(r);
526
+ let f = e(i.service, a.baseUrl), p = await oe({
521
527
  service: i.service,
522
528
  baseUrl: f
523
529
  }, u);
524
530
  if (!p) throw Error(`Не удалось загрузить metadata OData-сервиса '${i.service}'`);
525
- let m = ve(p, i.target);
526
- he(m, t, i);
527
- let h = oe(n.body, t), g = se(m, t), _ = ae(m, i, l, t), v = c ? {
531
+ let m = ge(p, i.target);
532
+ pe(m, t, i);
533
+ let h = ie(n.body, t), g = ae(m, t), _ = re(m, i, l, t), v = c ? {
528
534
  ...a,
529
535
  baseUrl: f,
530
536
  swCache: c
531
537
  } : {
532
538
  ...a,
533
539
  baseUrl: f
534
- }, y = ie(_, v, {
540
+ }, y = ne(_, v, {
535
541
  ...o,
536
542
  method: g,
537
543
  body: h,
538
544
  signal: d
539
545
  });
540
- return tt({
546
+ return nt({
541
547
  helperName: r,
542
548
  operation: t,
543
549
  odata: i,
@@ -556,25 +562,25 @@ function $(t, n, r) {
556
562
  } : { data: void 0 };
557
563
  };
558
564
  }
559
- function rt(e) {
560
- return __DEV__ ? $("create", e, "odataCreateFnDev") : C("create", e);
561
- }
562
565
  function it(e) {
563
- return __DEV__ ? $("update", e, "odataUpdateFnDev") : C("update", e);
566
+ return __DEV__ ? $("create", e, "odataCreateFnDev") : T("create", e);
564
567
  }
565
568
  function at(e) {
566
- return __DEV__ ? $("delete", e, "odataDeleteFnDev") : C("delete", e);
569
+ return __DEV__ ? $("update", e, "odataUpdateFnDev") : T("update", e);
567
570
  }
568
571
  function ot(e) {
569
- return __DEV__ ? $("read", e, "odataReadFnDev") : C("read", e);
572
+ return __DEV__ ? $("delete", e, "odataDeleteFnDev") : T("delete", e);
570
573
  }
571
574
  function st(e) {
572
- return __DEV__ ? $("query", e, "odataQueryFnDev") : C("query", e);
575
+ return __DEV__ ? $("read", e, "odataReadFnDev") : T("read", e);
573
576
  }
574
577
  function ct(e) {
575
- return __DEV__ ? $("fi", e, "odataFunctionImportFnDev") : C("fi", e);
578
+ return __DEV__ ? $("query", e, "odataQueryFnDev") : T("query", e);
579
+ }
580
+ function lt(e) {
581
+ return __DEV__ ? $("fi", e, "odataFunctionImportFnDev") : T("fi", e);
576
582
  }
577
583
  //#endregion
578
- export { h as BaseAppConfigURL, f as BaseODataDp0URL, l as BaseODataUI2URL, c as BaseODataURL, n as BaseUrlMap, L as ODATA_COLLECTION_BUST_SW_CACHE, I as ODATA_COLLECTION_DEFAULT_SW_CACHE, F as ODATA_COLLECTION_UPDATES_LOOKBACK_MS, R as ODATA_COLLECTION_UPDATES_SW_CACHE, d as SsoRequiredError, fe as applyODataMetadataVersion, i as configureODataProjectAdapter, N as createODataCollectionBaseQueryKey, P as createODataCollectionQueryKey, z as createODataCollectionUpdatesQueryKey, v as fetchBase, p as fetchDeleteFn, g as fetchJson, u as fetchJsonMutationFn, r as fetchJsonQueryFn, le as fetchMetadata, V as fetchODataCollectionUpdates, m as fetchODataJson, _ as fetchQueryFn, Ne as flattenODataDependentServices, b as getInputUrl, ce as getODataMetadataData, x as getODataProjectAdapter, a as isNoContentResponse, y as isSsoForm, t as normalizeODataServiceName, S as normalizeRelativePath, H as odataCollectionUpdatesQueryOptions, _e as odataCreateFn, rt as odataCreateFnDev, pe as odataDeleteFn, at as odataDeleteFnDev, T as odataFetch, ue as odataFunctionImportFn, ct as odataFunctionImportFnDev, ne as odataMetadataQueryOptions, re as odataQueryFn, st as odataQueryFnDev, me as odataReadFn, ot as odataReadFnDev, ge as odataUpdateFn, it as odataUpdateFnDev, o as recoverSsoSession, e as resolveODataBaseUrl, q as resolveODataCollectionSwCachePolicy, ee as resolveODataSapClient, Y as shouldRefreshODataCollectionCache, Pe as sortODataDependentSegmentItemsByChains, Ie as sortODataDependentServicesByChains, s as submitSsoForm, Ve as useODataCollection, He as useODataCollectionChains, Ue as useODataCollectionModel, X as useODataCollectionQuery, U as useODataCollectionUpdatesQuery, K as useODataEntity, W as useODataMetadata, w as useODataMetadataQuery, ye as useODataMetadataVersionQuery, Ge as useODataTableColumns, Ke as useTextServiceQuery };
584
+ export { h as BaseAppConfigURL, f as BaseODataDp0URL, l as BaseODataUI2URL, c as BaseODataURL, n as BaseUrlMap, V as ODATA_COLLECTION_BUST_SW_CACHE, B as ODATA_COLLECTION_DEFAULT_SW_CACHE, z as ODATA_COLLECTION_UPDATES_LOOKBACK_MS, H as ODATA_COLLECTION_UPDATES_SW_CACHE, d as SsoRequiredError, ue as applyODataMetadataVersion, i as configureODataProjectAdapter, L as createODataCollectionBaseQueryKey, R as createODataCollectionQueryKey, U as createODataCollectionUpdatesQueryKey, v as fetchBase, p as fetchDeleteFn, g as fetchJson, u as fetchJsonMutationFn, r as fetchJsonQueryFn, se as fetchMetadata, G as fetchODataCollectionUpdates, m as fetchODataJson, _ as fetchQueryFn, Ae as flattenODataDependentServices, b as getInputUrl, oe as getODataMetadataData, S as getODataProjectAdapter, a as isNoContentResponse, y as isSsoForm, t as normalizeODataServiceName, C as normalizeRelativePath, ze as odataCollectionUpdatesQueryOptions, he as odataCreateFn, it as odataCreateFnDev, de as odataDeleteFn, ot as odataDeleteFnDev, D as odataFetch, ce as odataFunctionImportFn, lt as odataFunctionImportFnDev, ee as odataMetadataQueryOptions, te as odataQueryFn, ct as odataQueryFnDev, fe as odataReadFn, st as odataReadFnDev, me as odataUpdateFn, at as odataUpdateFnDev, o as recoverSsoSession, e as resolveODataBaseUrl, He as resolveODataCollectionSwCachePolicy, x as resolveODataSapClient, Ue as shouldRefreshODataCollectionCache, je as sortODataDependentSegmentItemsByChains, Ne as sortODataDependentServicesByChains, s as submitSsoForm, Ge as useODataCollection, Ke as useODataCollectionChains, qe as useODataCollectionModel, We as useODataCollectionQuery, Be as useODataCollectionUpdatesQuery, Ve as useODataEntity, K as useODataMetadata, E as useODataMetadataQuery, _e as useODataMetadataVersionQuery, Ye as useODataTableColumns };
579
585
 
580
586
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/odata/createODataCollectionQueryKey.ts","../../src/odata/flattenODataDependentServices.ts","../../src/odata/sortODataDependentSegmentItemsByChains.ts","../../src/odata/sortODataDependentServicesByChains.ts","../../src/odata/fetchCollectionData.ts","../../src/odata/useODataCollectionUpdatesQuery.ts","../../src/odata/useODataMetadata.ts","../../src/odata/useODataEntity.ts","../../src/odata/useODataCollectionQuery.ts","../../src/odata/useODataCollection.ts","../../src/odata/useODataCollectionChains.ts","../../src/odata/useODataCollectionModel.ts","../../src/odata/useODataTableColumns.ts","../../src/odata/useTextServiceQuery.ts","../../src/odata/odataFetchFnDev.ts"],"sourcesContent":["import { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\nexport const createODataCollectionBaseQueryKey = () => [...odataBaseQueryKey, \"collection\"] as const;\n\nexport const createODataCollectionQueryKey = ({ service, target, limitedKeys, serverFilter }: ODataServiceCollectionConfig) =>\n\t[...createODataCollectionBaseQueryKey(), { service, target, limitedKeys, serverFilter }] as const;\n","import type { ODataDependentBaseProps, ODataDependentSegmentItem } from \"./types\";\n\n/**\n * Разворачивает зависимые OData-сервисы в плоский список segment-level элементов.\n */\nexport function flattenODataDependentServices(services: readonly ODataDependentBaseProps[]): ODataDependentSegmentItem[] {\n\tconst out: ODataDependentSegmentItem[] = [];\n\n\tfor (const [serviceIndex, service] of services.entries()) {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\n\t\tfor (const [segmentIndex, [id, segment]] of Object.entries(service.segments).entries()) {\n\t\t\tout.push({\n\t\t\t\tid,\n\t\t\t\tserviceKey,\n\t\t\t\tserviceIndex,\n\t\t\t\tsegmentIndex,\n\t\t\t\todata: service.odata,\n\t\t\t\tsegment,\n\t\t\t\tmodel: {\n\t\t\t\t\t...service.model,\n\t\t\t\t\tcodeKey: id\n\t\t\t\t},\n\t\t\t\tpanelVisibility: segment.panelVisibility ?? \"user\"\n\t\t\t});\n\t\t}\n\t}\n\n\treturn out;\n}\n","import { ODataDependentSegmentItem } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Сортирует плоские segment-level элементы по chain-порядку\n * и опционально накладывает пользовательский override.\n */\nexport function sortODataDependentSegmentItemsByChains(\n\titems: readonly ODataDependentSegmentItem[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentSegmentItem[] {\n\tconst chainOrderByService = new Map<string, Map<string, number>>();\n\n\tfor (const [serviceKey, chain] of Object.entries(chains)) {\n\t\tchainOrderByService.set(serviceKey, new Map(chain.map((item, index) => [item.codeKey, index])));\n\t}\n\n\tconst baseOrdered = [...items]\n\t\t.map((item, index) => ({\n\t\t\titem,\n\t\t\tindex\n\t\t}))\n\t\t.sort((left, right) => {\n\t\t\tif (left.item.serviceIndex !== right.item.serviceIndex) {\n\t\t\t\treturn left.item.serviceIndex - right.item.serviceIndex;\n\t\t\t}\n\n\t\t\tconst chainOrder = chainOrderByService.get(left.item.serviceKey);\n\t\t\tconst leftChainOrder = chainOrder?.get(left.item.id);\n\t\t\tconst rightChainOrder = chainOrder?.get(right.item.id);\n\n\t\t\tif (leftChainOrder !== undefined && rightChainOrder !== undefined) {\n\t\t\t\treturn leftChainOrder - rightChainOrder;\n\t\t\t}\n\t\t\tif (leftChainOrder !== undefined) return -1;\n\t\t\tif (rightChainOrder !== undefined) return 1;\n\n\t\t\tif (left.item.segmentIndex !== right.item.segmentIndex) {\n\t\t\t\treturn left.item.segmentIndex - right.item.segmentIndex;\n\t\t\t}\n\n\t\t\treturn left.index - right.index;\n\t\t});\n\n\tif (!orderOverrideIds?.length) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst availableIds = new Set(baseOrdered.map(({ item }) => item.id));\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => availableIds.has(id));\n\tif (normalizedOverride.length === 0) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\n\treturn [...baseOrdered]\n\t\t.sort((left, right) => {\n\t\t\tconst leftOverrideRank = overrideRank.get(left.item.id);\n\t\t\tconst rightOverrideRank = overrideRank.get(right.item.id);\n\n\t\t\tif (leftOverrideRank !== undefined && rightOverrideRank !== undefined) {\n\t\t\t\treturn leftOverrideRank - rightOverrideRank;\n\t\t\t}\n\t\t\tif (leftOverrideRank !== undefined) return -1;\n\t\t\tif (rightOverrideRank !== undefined) return 1;\n\n\t\t\treturn left.index - right.index;\n\t\t})\n\t\t.map(({ item }) => item);\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport { ODataDependentBaseProps } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Применяет пользовательский override порядка сегментов поверх уже рассчитанного базового порядка.\n *\n * Алгоритм:\n * 1. берёт только валидные id из `orderOverrideIds` (без дублей);\n * 2. поднимает эти id в начало в указанной последовательности;\n * 3. все остальные сегменты оставляет в исходном относительном порядке.\n */\nfunction applySegmentsOrderOverride(\n\tservices: readonly ODataDependentBaseProps[],\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tif (!orderOverrideIds?.length) return [...services];\n\n\tconst visibleIds = new Set<string>();\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tvisibleIds.add(segmentId);\n\t\t}\n\t}\n\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => visibleIds.has(id));\n\tif (normalizedOverride.length === 0) return [...services];\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\tconst fallbackRankStart = normalizedOverride.length;\n\tconst segmentRank = new Map<string, number>();\n\tlet fallbackRank = fallbackRankStart;\n\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tif (segmentRank.has(segmentId)) continue;\n\t\t\tsegmentRank.set(segmentId, overrideRank.get(segmentId) ?? fallbackRank++);\n\t\t}\n\t}\n\n\tconst withOrderedSegments = services.map((service) => {\n\t\tconst orderedEntries = Object.entries(service.segments).sort(\n\t\t\t([leftId], [rightId]) =>\n\t\t\t\t(segmentRank.get(leftId) ?? Number.MAX_SAFE_INTEGER) - (segmentRank.get(rightId) ?? Number.MAX_SAFE_INTEGER)\n\t\t);\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn [...withOrderedSegments].sort((leftService, rightService) => {\n\t\tconst leftFirstSegmentId = Object.keys(leftService.segments)[0];\n\t\tconst rightFirstSegmentId = Object.keys(rightService.segments)[0];\n\t\tconst leftRank = leftFirstSegmentId ? (segmentRank.get(leftFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\t\tconst rightRank = rightFirstSegmentId ? (segmentRank.get(rightFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\n\t\treturn leftRank - rightRank;\n\t});\n}\n\n/**\n * Сортирует сегменты сервисов по chain-порядку (от меньшего к большему)\n * и опционально накладывает пользовательский override.\n *\n * Если chain недоступен, сохраняет исходный порядок сегментов.\n *\n * @deprecated функционал должен быть вырезан и оставлен только с `sortODataDependentSegmentItemsByChains`\n */\nexport function sortODataDependentServicesByChains(\n\tservices: readonly ODataDependentBaseProps[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tconst sortedByChains = services.map((service) => {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\t\tconst chain = chains[serviceKey];\n\t\tif (!chain?.length) return service;\n\n\t\tconst chainOrder = new Map(chain.map((item, index) => [item.codeKey, index]));\n\t\tconst orderedEntries = Object.entries(service.segments).sort(([leftId], [rightId]) => {\n\t\t\tconst leftOrder = chainOrder.get(leftId);\n\t\t\tconst rightOrder = chainOrder.get(rightId);\n\n\t\t\tif (leftOrder !== undefined && rightOrder !== undefined) return leftOrder - rightOrder;\n\t\t\tif (leftOrder !== undefined) return -1;\n\t\t\tif (rightOrder !== undefined) return 1;\n\t\t\treturn compareStrings(leftId, rightId);\n\t\t});\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn applySegmentsOrderOverride(sortedByChains, orderOverrideIds);\n}\n","import { type CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { logError } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { odataFetch, type ODataFetchOptions } from \"./odataFetch\";\nimport { isNoContentResponse } from \"./transport\";\n\n// Тип для результата запроса справочника\ninterface ODataServiceResult<T extends CollectionItem> {\n\titems: T[];\n}\n\n/**\n * Загрузка данных справочника из OData сервиса\n */\nexport async function fetchCollectionData<T extends CollectionItem>(params: {\n\turl: string;\n\tquery?: ODataFetchOptions<T>;\n\tsignal: AbortSignal;\n}): Promise<ODataServiceResult<T>> {\n\tconst { url, query, signal } = params;\n\n\ttry {\n\t\t// Загружаем данные из OData сервиса\n\t\tconst response = await odataFetch<T, T[]>(url, query, { signal });\n\n\t\t// Считаем отсутствие данных ошибкой, ведь query запрос обязан вернуть корректное тело json\n\t\tif (isNoContentResponse(response)) {\n\t\t\tthrow new Error(\"отсутствует тело ответа\");\n\t\t}\n\n\t\tconst data = response.data;\n\n\t\t// Удаление ненужных полей.\n\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars\n\t\t\titems: data.map(({ ID, CNT, __metadata, __Parameters, ...item }) => item as T) /*, pairs, pairsMap */\n\t\t};\n\t} catch (error) {\n\t\tlogError(\"Ошибка загрузки справочника:\", error);\n\t\t// throw error;\n\n\t\treturn { items: [] };\n\t}\n}\n","import { parseDate } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { queryOptions, useQuery } from \"@tanstack/react-query\";\n\nimport { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { odataFetch } from \"./odataFetch\";\nimport { getODataProjectAdapter, resolveODataBaseUrl } from \"./odataProjectAdapter\";\n\nconst COLLECTION_UPDATES_BUILD_ID = __APP_BUILD_ID__;\nconst COLLECTION_UPDATES_STALE_TIME = 1000 * 60 * 60 * 4;\nexport const ODATA_COLLECTION_UPDATES_LOOKBACK_MS = 1000 * 60 * 60 * 24 * 7;\nexport const ODATA_COLLECTION_DEFAULT_SW_CACHE = \"ttl=forever;name=ref\";\nexport const ODATA_COLLECTION_BUST_SW_CACHE = \"bust=forever;name=ref\";\nexport const ODATA_COLLECTION_UPDATES_SW_CACHE = \"ttl=4h;name=ref-updates\";\n\ninterface ODataCollectionUpdateRecord {\n\tentityName: string;\n\tlastChanged: string;\n}\n\nexport interface ODataCollectionUpdateItem extends ODataCollectionUpdateRecord {\n\tlastChangedAt: Date | null;\n}\n\nexport interface ODataCollectionUpdatesResult {\n\titems: ODataCollectionUpdateItem[];\n\tbyEntityName: Record<string, ODataCollectionUpdateItem>;\n\tfetchedAt: number;\n\tcoverageStartedAt: number;\n}\n\nexport interface ODataCollectionUpdatesOptions {\n\tstaleTime?: number;\n}\n\nexport const createODataCollectionUpdatesQueryKey = () =>\n\t[...odataBaseQueryKey, \"collection-updates\", { buildId: COLLECTION_UPDATES_BUILD_ID }] as const;\n\nfunction normalizeCollectionUpdateRecord(record: ODataCollectionUpdateRecord): ODataCollectionUpdateItem {\n\treturn {\n\t\t...record,\n\t\tlastChangedAt: parseDate(record.lastChanged)\n\t};\n}\n\nfunction normalizeCollectionUpdates(records: ODataCollectionUpdateRecord[], fetchedAt: number): ODataCollectionUpdatesResult {\n\tconst items = records.map(normalizeCollectionUpdateRecord);\n\tconst byEntityName = items.reduce<Record<string, ODataCollectionUpdateItem>>((acc, item) => {\n\t\tif (item.entityName) {\n\t\t\tacc[item.entityName] = item;\n\t\t}\n\n\t\treturn acc;\n\t}, {});\n\n\treturn { items, byEntityName, fetchedAt, coverageStartedAt: fetchedAt - ODATA_COLLECTION_UPDATES_LOOKBACK_MS };\n}\n\n/**\n * Загружает компактный список справочников, изменённых за последние 7 дней.\n * Сам список живёт отдельно от данных справочников и управляет их точечной инвалидацией.\n */\nexport function fetchODataCollectionUpdates() {\n\treturn async ({ signal }: { signal: AbortSignal }): Promise<ODataCollectionUpdatesResult> => {\n\t\tconst requestStartedAt = Date.now();\n\t\tconst endpoint = getODataProjectAdapter().collectionUpdates;\n\t\tif (!endpoint) return normalizeCollectionUpdates([], requestStartedAt);\n\n\t\tconst response = await odataFetch<ODataCollectionUpdateRecord, ODataCollectionUpdateRecord[]>(\n\t\t\t`/${endpoint.service}/${endpoint.target}`,\n\t\t\t{\n\t\t\t\tbaseUrl: resolveODataBaseUrl(endpoint.service, endpoint.baseUrl),\n\t\t\t\tswCache: ODATA_COLLECTION_UPDATES_SW_CACHE\n\t\t\t},\n\t\t\t{ signal }\n\t\t);\n\n\t\treturn normalizeCollectionUpdates(response.data, Math.max(requestStartedAt, Date.now()));\n\t};\n}\n\n/**\n * Описывает общий TanStack Query со списком обновлённых справочников.\n * Query сохраняется в IndexedDB и дополнительно кешируется Service Worker на короткий TTL.\n *\n * При отсутствии endpoint queryFn возвращает пустой успешный результат без сетевого запроса.\n * Query должен оставаться активным, потому что зависимые справочники ждут его завершения.\n */\nexport const odataCollectionUpdatesQueryOptions = (options: ODataCollectionUpdatesOptions = {}) =>\n\tqueryOptions({\n\t\tqueryKey: createODataCollectionUpdatesQueryKey(),\n\t\tqueryFn: fetchODataCollectionUpdates(),\n\t\tmeta: persistedQueryMeta,\n\t\tstaleTime: options.staleTime ?? COLLECTION_UPDATES_STALE_TIME,\n\t\tgcTime: Infinity\n\t});\n\nexport function useODataCollectionUpdatesQuery(options: ODataCollectionUpdatesOptions = {}) {\n\treturn useQuery(odataCollectionUpdatesQueryOptions(options));\n}\n","import { useODataMetadataQuery } from \"./useODataMetadataQuery\";\n\nimport type { ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Возвращает metadata конкретной OData-сущности по имени сервиса и сущности.\n *\n * Хук не добавляет собственную бизнес-логику и служит публичной тонкой\n * прослойкой над `useODataMetadataQuery(...)`.\n */\nexport function useODataMetadata(odata: ODataServiceConfig) {\n\tconst { data, dataUpdatedAt = 0, isLoading, isLoadingError } = useODataMetadataQuery({ service: odata.service });\n\tconst metadata = data?.entities[odata.target];\n\n\tif (!isLoading && !metadata && data?.functionImports[odata.target]) {\n\t\tthrow new Error(`OData target '${odata.target}' является FunctionImport и не может использоваться как сущность`);\n\t}\n\n\tif (isLoadingError) {\n\t\tthrow new Error(`Ошибка загрузки метаданных сервиса ${odata.service}`);\n\t}\n\n\treturn { metadata, metadataUpdatedAt: dataUpdatedAt, isLoading };\n}\n","import { useMemo } from \"react\";\n\nimport { buildEntityPath, type ODataServiceConfig, type ODataValue } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nconst throwErrorText = \"Использование actions недопустимо до окончания загрузки metadata\";\n\n// function throwNoMetadata() {\n// \tif (__DEV__) {\n// \t\tthrow new Error(throwErrorText);\n// \t}\n// \treturn undefined;\n// }\n\nexport type ODataEntity = Omit<ReturnType<typeof useODataEntity>, \"isLoading\">;\n\nexport function useODataEntity(odata: ODataServiceConfig) {\n\tconst { metadata, metadataUpdatedAt, isLoading } = useODataMetadata(odata);\n\n\tconst actions = useMemo(() => {\n\t\tconst getEntityPath = (values: Record<string, ODataValue> = {}) => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn buildEntityPath(metadata, odata, values);\n\t\t};\n\t\tconst getKeys = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns?.map((c) => c.id);\n\t\t};\n\t\tconst getKeyPairs = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns\n\t\t\t\t?.filter((c) => c.semanticType === \"code\" && c.linkedColumnId)\n\t\t\t\t.map((c) => ({ codeKey: c.id, textKey: c.linkedColumnId }) as CollectionPair);\n\t\t};\n\t\tconst getKeyPairsMap = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\tconst pairs: Record<string, string> = {};\n\n\t\t\tfor (const column of metadata.columns ?? []) {\n\t\t\t\tif (column.semanticType === \"code\" && column.linkedColumnId) {\n\t\t\t\t\tpairs[column.id] = column.linkedColumnId;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn pairs;\n\t\t};\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Получить строку запроса `/service/entity(parameters)/Results`\n\t\t\t */\n\t\t\tgetEntityPath,\n\t\t\t/**\n\t\t\t * Получить все ключи сущности\n\t\t\t */\n\t\t\tgetKeys,\n\t\t\t/**\n\t\t\t * Получить список ключей в формате `{ codeKey, textKey }`\n\t\t\t */\n\t\t\tgetKeyPairs,\n\t\t\t/**\n\t\t\t * Получить словать ключей в формате `{ code: text }`\n\t\t\t */\n\t\t\tgetKeyPairsMap\n\t\t};\n\t}, [odata, metadata]);\n\n\treturn { config: odata, metadata, metadataUpdatedAt, isLoading, actions };\n}\n","import { useEffect, useMemo } from \"react\";\n\nimport { buildSeparatedArrays, type CollectionItem, type CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { useQuery, useQueryClient, UseQueryResult } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { fetchCollectionData } from \"./fetchCollectionData\";\nimport { ODataCollectionConfig } from \"./types\";\nimport {\n\tODATA_COLLECTION_BUST_SW_CACHE,\n\tODATA_COLLECTION_DEFAULT_SW_CACHE,\n\tODataCollectionUpdateItem,\n\tuseODataCollectionUpdatesQuery\n} from \"./useODataCollectionUpdatesQuery\";\nimport { useODataEntity } from \"./useODataEntity\";\n\nexport interface ODataCollectionResult<T extends CollectionItem> {\n\titems: T[];\n\tkeyPairs: CollectionPair[];\n\tkeyPairsMap: Record<string, string>;\n\tseparated: Record<string, T[]>;\n\tchain: { codeKey: string; count: number }[];\n\tcount: number;\n\tcacheUpdatedAt: number;\n}\n\ninterface ODataCollectionCacheRefreshContext {\n\tupdate?: ODataCollectionUpdateItem;\n\tmetadataUpdatedAt?: number;\n\tupdatesCoverageStartedAt?: number;\n}\n\nexport function resolveODataCollectionSwCachePolicy(swCache: string, shouldBust: boolean) {\n\tif (!shouldBust) return swCache;\n\n\tconst normalized = swCache.trim().toLowerCase();\n\tif (normalized === \"off\" || normalized.startsWith(\"bust=\")) return swCache;\n\tif (normalized.startsWith(\"ttl=\")) return swCache.replace(/^\\s*ttl=/i, \"bust=\");\n\n\treturn ODATA_COLLECTION_BUST_SW_CACHE;\n}\n\nfunction isUsableTimestamp(value: number | undefined): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Определяет, нужно ли обновить конкретный справочник по списку изменений.\n * Сравнение идёт с cacheUpdatedAt, который сохраняется вместе с данными справочника.\n */\nexport function shouldRefreshODataCollectionCache<T extends CollectionItem>(\n\tcontext: ODataCollectionCacheRefreshContext,\n\tcachedData: ODataCollectionResult<T> | undefined\n) {\n\tconst cacheUpdatedAt = cachedData?.cacheUpdatedAt ?? 0;\n\tconst updateChangedAt = context.update?.lastChangedAt?.getTime();\n\n\tif (isUsableTimestamp(updateChangedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (updateChangedAt > cacheUpdatedAt) return true;\n\t}\n\n\tif (isUsableTimestamp(context.metadataUpdatedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (context.metadataUpdatedAt > cacheUpdatedAt) return true;\n\t}\n\n\t/**\n\t * Бэкенд отдаёт список изменений справочников только за последнюю неделю.\n\t * Если локальный справочник старше этого окна, отсутствие target в списке\n\t * больше не доказывает актуальность, поэтому обновляем только открытый справочник.\n\t */\n\tif (isUsableTimestamp(context.updatesCoverageStartedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (cacheUpdatedAt < context.updatesCoverageStartedAt) return true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Универсальный хук для получения данных из OData сервиса.\n * Заменяет функционал TextDataService из SAP UI5.\n */\nexport function useODataCollectionQuery<T extends CollectionItem>(odata: ODataCollectionConfig): UseQueryResult<ODataCollectionResult<T>> {\n\tconst {\n\t\tservice,\n\t\ttarget,\n\t\tlimitedKeys,\n\t\texcludeEmpty,\n\t\tsortByCode,\n\t\tserverFilter,\n\t\tclientFilter,\n\t\tswCache = ODATA_COLLECTION_DEFAULT_SW_CACHE\n\t} = odata;\n\tconst queryClient = useQueryClient();\n\tconst { actions, metadata, metadataUpdatedAt, isLoading } = useODataEntity(odata);\n\tconst updatesQuery = useODataCollectionUpdatesQuery();\n\n\tconst queryKey = useMemo(\n\t\t() => createODataCollectionQueryKey({ service, target, limitedKeys, serverFilter }),\n\t\t[service, target, limitedKeys, serverFilter]\n\t);\n\tconst cachedData = queryClient.getQueryData<ODataCollectionResult<T>>(queryKey);\n\tconst collectionUpdate = updatesQuery.data?.byEntityName[target];\n\tconst shouldBustCollectionCache = shouldRefreshODataCollectionCache(\n\t\t{\n\t\t\tupdate: collectionUpdate,\n\t\t\tmetadataUpdatedAt,\n\t\t\tupdatesCoverageStartedAt: updatesQuery.data?.coverageStartedAt\n\t\t},\n\t\tcachedData\n\t);\n\tconst effectiveSwCache = resolveODataCollectionSwCachePolicy(swCache, shouldBustCollectionCache);\n\tconst updatesReady = updatesQuery.isError || (updatesQuery.isSuccess && !updatesQuery.isFetching);\n\n\tuseEffect(() => {\n\t\tif (!cachedData || !shouldBustCollectionCache) return;\n\n\t\tvoid queryClient.invalidateQueries({ queryKey });\n\t}, [cachedData, queryClient, queryKey, shouldBustCollectionCache]);\n\n\treturn useQuery({\n\t\tqueryKey,\n\t\tqueryFn: async ({ signal }) => {\n\t\t\tconst requestStartedAt = Date.now();\n\t\t\tconst selectKeys = limitedKeys ? [...limitedKeys] : actions.getKeys();\n\t\t\tconst keyPairs = actions.getKeyPairs();\n\t\t\tconst keyPairsMap = actions.getKeyPairsMap();\n\n\t\t\tif (limitedKeys) {\n\t\t\t\tfor (const k of limitedKeys) {\n\t\t\t\t\tconst keyText = keyPairsMap[k];\n\t\t\t\t\tif (keyText && !selectKeys.includes(keyText)) {\n\t\t\t\t\t\tselectKeys.push(keyText);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { items } = await fetchCollectionData<T>({\n\t\t\t\turl: `/${service}/${target}`,\n\t\t\t\tquery: {\n\t\t\t\t\tselect: selectKeys,\n\t\t\t\t\texpression: serverFilter,\n\t\t\t\t\tswCache: effectiveSwCache\n\t\t\t\t},\n\t\t\t\tsignal\n\t\t\t});\n\n\t\t\tlet filterdItems = items;\n\t\t\tif (clientFilter) {\n\t\t\t\tfilterdItems = items.filter(clientFilter);\n\t\t\t}\n\n\t\t\tconst separated = buildSeparatedArrays<T>(filterdItems, keyPairs, excludeEmpty, sortByCode);\n\n\t\t\t// Рассчитать порядок от меньшего к большему\n\t\t\tconst chain = keyPairs\n\t\t\t\t.map((pair) => ({ codeKey: pair.codeKey, count: separated[pair.codeKey].length }))\n\t\t\t\t.sort((a, b) => a.count - b.count);\n\n\t\t\treturn {\n\t\t\t\titems: filterdItems,\n\t\t\t\tkeyPairs,\n\t\t\t\tkeyPairsMap,\n\t\t\t\tseparated,\n\t\t\t\tchain,\n\t\t\t\tcount: filterdItems.length,\n\t\t\t\tcacheUpdatedAt: Math.max(requestStartedAt, Date.now(), collectionUpdate?.lastChangedAt?.getTime() ?? 0, metadataUpdatedAt)\n\t\t\t};\n\t\t},\n\t\tenabled: Boolean(!isLoading && metadata && service && target && updatesReady),\n\t\tmeta: persistedQueryMeta,\n\t\t/**\n\t\t * Клиентский кеш можно держать не долго, чтобы он мог чаще дергать SW\n\t\t */\n\t\tstaleTime: 1000 * 60 * 60 * 2,\n\t\t/**\n\t\t * Если справочник не используется более часа, то можно из памяти выгрузить.\n\t\t */\n\t\tgcTime: 1000 * 60 * 60 * 1\n\t});\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\n\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataCollectionConfig, ODataCollectionModel } from \"./types\";\nimport { useODataCollectionQuery } from \"./useODataCollectionQuery\";\n\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\ninterface UseODataCollectionProps {\n\todata: ODataCollectionConfig;\n\tmodel: Required<ODataCollectionModel>;\n\n\t/**\n\t * Размер страницы для виртуализации.\n\t */\n\tpageSize?: number;\n\n\tfilter?: (item: CollectionItem) => boolean;\n}\n\nexport function useODataCollection({\n\todata,\n\tmodel,\n\t// filter,\n\tpageSize = 50\n}: UseODataCollectionProps) {\n\tconst { codeKey, maxVisibleItems } = model;\n\tconst { data: rawData, isLoading, isError, refetch } = useODataCollectionQuery(odata);\n\n\tconst textKey = rawData?.keyPairsMap[codeKey] ?? \"\";\n\n\t// Клиент для инвалидации запросов\n\tconst queryClient = useQueryClient();\n\n\tconst [filteredKeys, setFilteredKeys] = useState<Set<string>>();\n\n\tconst debounceTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n\t/**\n\t * itemsMap - индекс элементов для быстрого поиска\n\t * orderedKeys - упорядоченный список ключей для сохранения порядка\n\t */\n\tconst { itemsMap, separatedItems, orderedKeys } = useMemo(() => {\n\t\tconst itemsMap = new Map<string, CollectionItem>();\n\t\tconst orderedKeys = [] as string[];\n\t\tlet separatedItems: CollectionItem[] = [];\n\n\t\tif (rawData && rawData.separated[codeKey]) {\n\t\t\tseparatedItems = rawData.separated[codeKey];\n\n\t\t\tfor (const item of separatedItems) {\n\t\t\t\tconst key = item[codeKey];\n\t\t\t\tif (key) {\n\t\t\t\t\titemsMap.set(key, item);\n\t\t\t\t\torderedKeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { itemsMap, separatedItems, orderedKeys };\n\t}, [rawData, codeKey]);\n\n\t// Создание индекса поиска для текстовых полей\n\tconst buildSearchIndex = useCallback(\n\t\t(field: string) => {\n\t\t\tconst items = rawData?.separated[codeKey];\n\n\t\t\tif (!items) {\n\t\t\t\treturn new Map<string, Set<string>>();\n\t\t\t}\n\n\t\t\tconst index = new Map<string, Set<string>>();\n\n\t\t\t// Создаем индекс по префиксам для быстрого поиска\n\t\t\tfor (const item of items) {\n\t\t\t\tconst value = item[field]?.toLowerCase();\n\t\t\t\tif (!value) continue;\n\n\t\t\t\t// Индексируем по префиксам длиной 1-5 символов\n\t\t\t\tfor (let i = 1; i <= Math.min(5, value.length); i++) {\n\t\t\t\t\tconst prefix = value.substring(0, i);\n\t\t\t\t\tif (!index.has(prefix)) {\n\t\t\t\t\t\tindex.set(prefix, new Set<string>());\n\t\t\t\t\t}\n\t\t\t\t\tindex.get(prefix)!.add(item[codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn index;\n\t\t},\n\t\t[rawData, codeKey]\n\t);\n\n\t/**\n\t * Устанавливает несколько фильтров зависимостей.\n\t *\n\t * Сформированный список ключей пойдёт в фильтрацию элементов текущей коллекции по `codeKey`\n\t */\n\tconst setFilteredItems = useCallback(\n\t\t(filters: CollectionItem[] | undefined) => {\n\t\t\tsetFilteredKeys(() => {\n\t\t\t\tif (filters?.length) {\n\t\t\t\t\treturn new Set(filters.map((item) => item[codeKey]));\n\t\t\t\t}\n\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t},\n\t\t[codeKey]\n\t);\n\n\tconst getItems = useCallback(\n\t\t(\n\t\t\tpredicate?: (codeValue: string, textValue: string) => boolean,\n\t\t\tcurrentSelectedKeys?: readonly CollectionItem[]\n\t\t): CollectionItem[] => {\n\t\t\tif (!orderedKeys.length) return [];\n\n\t\t\tconst limit = maxVisibleItems;\n\t\t\tconst selectedKeysSet = new Set<string>();\n\t\t\tconst resultItems: CollectionItem[] = [];\n\n\t\t\tif (currentSelectedKeys?.length) {\n\t\t\t\t// Быстрое заполнение Set без создания временного массива\n\t\t\t\tfor (let i = 0; i < currentSelectedKeys.length; i++) {\n\t\t\t\t\tselectedKeysSet.add(currentSelectedKeys[i][codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet count = 0;\n\n\t\t\tconst existsDependencies = filteredKeys && filteredKeys.size > 0;\n\n\t\t\t// Единый проход с ранним выходом по лимиту\n\t\t\tfor (const key of orderedKeys) {\n\t\t\t\tif (count >= limit) break;\n\n\t\t\t\tconst item = itemsMap.get(key);\n\t\t\t\tif (!item) continue;\n\n\t\t\t\t// Проверка на исключение выбранных ключей\n\t\t\t\tif (selectedKeysSet.size > 0 && selectedKeysSet.has(key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst itemCode = item[codeKey];\n\n\t\t\t\tif (existsDependencies && !filteredKeys.has(itemCode)) continue;\n\n\t\t\t\t// Проверка внешнего предиката\n\t\t\t\tif (predicate && !predicate(itemCode, item[textKey])) continue;\n\n\t\t\t\tresultItems.push(item);\n\t\t\t\tcount++;\n\t\t\t}\n\n\t\t\treturn resultItems;\n\t\t},\n\t\t[orderedKeys, maxVisibleItems, codeKey, itemsMap, filteredKeys, textKey]\n\t);\n\n\t/**\n\t * Получает страницу данных для виртуализации.\n\t */\n\tconst getPage = useCallback(\n\t\t(pageIndex: number): CollectionItem[] => {\n\t\t\tconst allItems = rawData?.separated[codeKey] || [];\n\t\t\tconst start = pageIndex * pageSize;\n\t\t\tconst end = start + pageSize;\n\t\t\treturn allItems.slice(start, end);\n\t\t},\n\t\t[rawData, pageSize, codeKey]\n\t);\n\n\t/**\n\t * Находит несколько элементов по ключам.\n\t */\n\tconst findSourceItemsByKeys = useCallback(\n\t\t(key: string, keys: string[]) => {\n\t\t\tif (!rawData) return [];\n\n\t\t\tconst keysSet = new Set<string>(keys);\n\t\t\treturn rawData.items.filter((item) => keysSet.has(item[key]));\n\t\t},\n\t\t[rawData]\n\t);\n\n\t/**\n\t * Дебаунсинг для частых операций.\n\t */\n\tconst debounce = useCallback((key: string, fn: () => void, delay: number = 200) => {\n\t\t// Очищаем предыдущий таймер\n\t\tif (debounceTimers.current.has(key)) {\n\t\t\tclearTimeout(debounceTimers.current.get(key)!);\n\t\t}\n\n\t\t// Устанавливаем новый таймер\n\t\tconst timer = setTimeout(fn, delay);\n\t\tdebounceTimers.current.set(key, timer);\n\t}, []);\n\n\t/**\n\t * Очищает все дебаунс таймеры.\n\t */\n\tconst clearDebounceTimers = useCallback(() => {\n\t\tfor (const timer of debounceTimers.current.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tdebounceTimers.current.clear();\n\t}, []);\n\n\t// Очистка таймеров при размонтировании\n\tuseMemo(() => {\n\t\treturn () => {\n\t\t\tclearDebounceTimers();\n\t\t};\n\t}, [clearDebounceTimers]);\n\n\treturn {\n\t\t// Состояние данных\n\t\tdata: rawData,\n\t\tisLoading,\n\t\tisError,\n\n\t\tcodeKey,\n\t\ttextKey,\n\n\t\t// Функции для работы с коллекцией\n\t\tgetItems,\n\t\tfindSourceItemsByKeys,\n\t\tsetFilteredItems,\n\t\tgetPage,\n\t\tbuildSearchIndex,\n\t\tdebounce,\n\n\t\t// Вспомогательные данные\n\t\titemsMap,\n\t\tseparatedItems,\n\t\torderedKeys,\n\n\t\t// Управление запросом\n\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\trefetch,\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\tinvalidate: () => queryClient.invalidateQueries({ queryKey: createODataCollectionQueryKey(odata) }),\n\n\t\t// Метаданные для виртуализации\n\t\ttotalCount: rawData?.separated[codeKey]?.length || 0,\n\t\tpageSize\n\t};\n}\n","import { useEffect, useMemo, useState } from \"react\";\n\nimport { Query, useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Используется для получения последовательностей кодов.\n */\nexport function useODataCollectionChains(params: ODataServiceCollectionConfig[]) {\n\tconst queryClient = useQueryClient();\n\tconst [chains, setChains] = useState<ODataChainsMap>({});\n\n\tconst trackedKeys = useMemo(() => params.map((p) => createODataCollectionQueryKey(p)), [params]);\n\n\tuseEffect(() => {\n\t\tfunction updateChains() {\n\t\t\tconst newChains: ODataChainsMap = {};\n\n\t\t\tfor (const p of params) {\n\t\t\t\tconst key = createODataCollectionQueryKey(p);\n\t\t\t\tconst cached = queryClient.getQueryData<{ chain: { codeKey: string; count: number }[] }>(key);\n\t\t\t\tif (cached?.chain) {\n\t\t\t\t\tnewChains[`${p.service}.${p.target}`] = cached.chain;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetChains((prev) => {\n\t\t\t\t// не обновлять стейт, если данные не изменились (во избежание лишних рендеров)\n\t\t\t\tconst same =\n\t\t\t\t\tObject.keys(prev).length === Object.keys(newChains).length &&\n\t\t\t\t\tObject.entries(newChains).every(([k, v]) => prev[k] === v);\n\t\t\t\treturn same ? prev : newChains;\n\t\t\t});\n\t\t}\n\n\t\t// Первичная загрузка (на случай, если данные уже в кэше)\n\t\tupdateChains();\n\n\t\t// Подписка на изменения кэша\n\t\tconst unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n\t\t\t// Проверяем, затрагивает ли событие один из наших trackedKeys\n\t\t\tif (event?.query) {\n\t\t\t\tconst query = event.query as Query;\n\t\t\t\tconst isTracked = trackedKeys.some((key) => JSON.stringify(key) === JSON.stringify(query.queryKey));\n\t\t\t\tif (isTracked) {\n\t\t\t\t\tupdateChains();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn unsubscribe;\n\t}, [params, queryClient, trackedKeys]);\n\n\treturn chains;\n}\n","import { useState } from \"react\";\n\nimport { useODataCollectionStore } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { ODataCollectionModel } from \"./types\";\n\nexport function useODataCollectionModel(model: ODataCollectionModel): Required<ODataCollectionModel> {\n\t// NOTE: без подписки, потому что эти данные в рантайме не предполагается изменять в ближайшее время.\n\n\t// const defaultMaxVisibleItems = odataCollectionConfig.useMaxVisibleItems();\n\t// const defaultMinSearchCodeLength = odataCollectionConfig.useMinSearchCodeLength();\n\t// const defaultMinSearchTextLength = odataCollectionConfig.useMinSearchTextLength();\n\t// const defaultSearchDebounceDelay = odataCollectionConfig.useSearchDebounce();\n\n\tconst [stableModel] = useState(() => {\n\t\tconst defaultState = useODataCollectionStore.getState();\n\n\t\tconst {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems = defaultState.defaultMaxVisibleItems,\n\t\t\tminSearchCodeLength = defaultState.defaultMinSearchCodeLength,\n\t\t\tminSearchTextLength = defaultState.defaultMinSearchTextLength,\n\t\t\tsearchDebounceDelay = defaultState.defaultSearchDebounceDelay\n\t\t} = model;\n\t\treturn {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems,\n\t\t\tminSearchCodeLength,\n\t\t\tminSearchTextLength,\n\t\t\tsearchDebounceDelay\n\t\t};\n\t});\n\n\treturn stableModel;\n}\n","import { useMemo } from \"react\";\n\nimport {\n\ttype TableColumnDef,\n\ttype TableColumnFormattingMetaInput,\n\tcreateTableColumnVisibilityFromODataMetadata,\n\tcreateTableColumnsFromODataMetadata,\n\tenrichTableColumnsWithODataFormatting,\n\tresolveStableColumnId\n} from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { EntityColumnProperty, EntityMetadata, ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Собирает visibility-state только для тех leaf-колонок, которые сопоставились с metadata.\n */\nfunction collectMatchedColumnVisibility<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tvisibilityById: Readonly<Record<string, boolean>>\n): Record<string, boolean> {\n\tconst matchedVisibility: Record<string, boolean> = {};\n\n\tconst visitLeafColumns = (nestedColumns: readonly TableColumnDef<TData>[]) => {\n\t\tfor (const column of nestedColumns) {\n\t\t\tif (\"columns\" in column && Array.isArray(column.columns) && column.columns.length > 0) {\n\t\t\t\tvisitLeafColumns(column.columns as TableColumnDef<TData>[]);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst columnId = resolveStableColumnId(column);\n\t\t\tif (!columnId || !(columnId in visibilityById)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmatchedVisibility[columnId] = visibilityById[columnId];\n\t\t}\n\t};\n\n\tvisitLeafColumns(columns);\n\n\treturn matchedVisibility;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `build`.\n */\nexport interface UseODataTableColumnsBuildConfig extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим генерации колонок только по metadata.\n\t */\n\tmode: \"build\";\n\t/**\n\t * Позволяет определить видимость колонки при генерации.\n\t */\n\tresolveVisible?: (column: EntityColumnProperty) => boolean;\n\t/**\n\t * Позволяет переопределить заголовок колонки при генерации.\n\t */\n\tresolveHeader?: (column: EntityColumnProperty) => string;\n\t/**\n\t * Позволяет сразу навесить formatting-конфиг на generated column.\n\t */\n\tresolveFormatting?: (column: EntityColumnProperty) => TableColumnFormattingMetaInput | undefined;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `enrich`.\n */\nexport interface UseODataTableColumnsEnrichConfig<TData extends object> extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим обогащения уже существующих колонок.\n\t */\n\tmode: \"enrich\";\n\t/**\n\t * Существующий набор колонок для дозаполнения `meta.formatting.role/type`.\n\t */\n\tcolumns: readonly TableColumnDef<TData>[];\n}\n\n/**\n * Универсальный конфиг hook-адаптера колонок.\n */\nexport type UseODataTableColumnsConfig<TData extends object = Record<string, unknown>> =\n\tUseODataTableColumnsBuildConfig | UseODataTableColumnsEnrichConfig<TData>;\n\n/**\n * Результат работы hook-адаптера колонок.\n */\nexport interface UseODataTableColumnsResult<TData extends object> {\n\t/**\n\t * Итоговый набор колонок для `Table` или `TreeTable`.\n\t */\n\tcolumns: TableColumnDef<TData>[];\n\t/**\n\t * Стартовая карта видимости колонок для TanStack Table.\n\t */\n\tdefaultColumnVisibility: Record<string, boolean> | undefined;\n\t/**\n\t * Метаданные сущности, если они уже загружены.\n\t */\n\tmetadata: EntityMetadata | undefined;\n\t/**\n\t * Признак загрузки metadata.\n\t */\n\tisLoading: boolean;\n}\n\n/**\n * Возвращает колонки для `Table`/`TreeTable` на основе OData metadata.\n *\n * В режиме `build` генерирует базовый набор колонок из `metadata.columns`.\n * В режиме `enrich` дозаполняет уже существующие колонки typed-formatting контекстом.\n */\nexport function useODataTableColumns<TData extends object = Record<string, unknown>>(\n\tconfig: UseODataTableColumnsConfig<TData>\n): UseODataTableColumnsResult<TData> {\n\tconst { metadata, isLoading } = useODataMetadata(config);\n\n\tconst columns = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn config.mode === \"build\" ? [] : [...config.columns];\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnsFromODataMetadata<TData>(metadata.columns, {\n\t\t\t\tresolveHeader: config.resolveHeader,\n\t\t\t\tresolveFormatting: config.resolveFormatting\n\t\t\t});\n\t\t}\n\n\t\treturn enrichTableColumnsWithODataFormatting(config.columns, metadata.columns);\n\t}, [config, metadata]);\n\n\tconst defaultColumnVisibility = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnVisibilityFromODataMetadata(metadata.columns, {\n\t\t\t\tresolveVisible: config.resolveVisible\n\t\t\t});\n\t\t}\n\n\t\tconst visibilityById = createTableColumnVisibilityFromODataMetadata(metadata.columns);\n\n\t\treturn collectMatchedColumnVisibility(config.columns, visibilityById);\n\t}, [config, metadata]);\n\n\treturn {\n\t\tcolumns,\n\t\tdefaultColumnVisibility,\n\t\tmetadata,\n\t\tisLoading\n\t};\n}\n","import { useODataCollectionQuery } from \"./useODataCollectionQuery\";\n\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nexport function useTextServiceQuery<T extends CollectionItem>(target: string) {\n\treturn useODataCollectionQuery<T>({ service: \"TEXT_DICTIONARY_SRV\", target });\n}\n","import { notify } from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { QueryClient } from \"@tanstack/react-query\";\n\nimport { buildODataFetchRequest, ODataFetchRequestPreview } from \"./odataFetch\";\nimport {\n\tODataArrayOperationMethod,\n\tODataCreateFnOptions,\n\tODataDeleteFnOptions,\n\todataFetchFn,\n\tODataFetchFnImplementationArgs,\n\tODataFetchFnRequest,\n\tODataFetchFnRunner,\n\tODataFetchFnSharedOptions,\n\tODataFunctionImportFnOptions,\n\tODataQueryArrayTransform,\n\tODataQueryFnOptions,\n\tODataQuerySingleTransform,\n\tODataReadFnOptions,\n\tODataSingleFetchFnRequest,\n\tODataSingleOperationMethod,\n\tODataSingleTransform,\n\tODataUpdateFnOptions\n} from \"./odataFetchFn\";\nimport {\n\tbuildTargetPath,\n\tisFunctionImportMetadata,\n\tresolveODataTarget,\n\tresolveRequestBody,\n\tresolveRequestMethod,\n\tvalidateODataOperation\n} from \"./odataFetchFnHelpers\";\nimport { resolveODataBaseUrl } from \"./transport\";\nimport { getODataMetadataData } from \"./useODataMetadataQuery\";\n\nimport type {\n\tODataOperationMethod,\n\tODataServiceConfig,\n\tODataTargetMetadata,\n\tUnwrappedODataParameters,\n\tWrappedODataParameters\n} from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\ntype ODataDevHelperName =\n\t| \"odataFetchFnDev\"\n\t| \"odataCreateFnDev\"\n\t| \"odataUpdateFnDev\"\n\t| \"odataDeleteFnDev\"\n\t| \"odataReadFnDev\"\n\t| \"odataQueryFnDev\"\n\t| \"odataFunctionImportFnDev\";\n\ntype ODataFetchFnDevOptions<I> = ODataFetchFnSharedOptions<I> & {\n\tparams?: WrappedODataParameters;\n\tbody?: unknown;\n\ttransform?: unknown;\n};\n\ntype ODataDevRequestLogInfo = {\n\thelperName: ODataDevHelperName;\n\toperation: ODataOperationMethod;\n\todata: ODataServiceConfig;\n\ttarget: ODataTargetMetadata;\n\ttargetPath: string;\n\trequest: ODataFetchRequestPreview;\n\trequestMethod: string;\n\tparams: WrappedODataParameters;\n\tqueryOptions: unknown;\n\tbody: string | undefined;\n\tautoParse: boolean | undefined;\n\thasTransform: boolean;\n};\n\nfunction getConsole() {\n\treturn globalThis.console;\n}\n\nfunction headersToRecord(headers: HeadersInit | undefined) {\n\tconst result: Record<string, string> = {};\n\tnew Headers(headers).forEach((value, key) => {\n\t\tresult[key] = value;\n\t});\n\n\treturn result;\n}\n\nfunction parseRequestBodyForLog(body: BodyInit | null | undefined): unknown {\n\tif (body === undefined || body === null) return undefined;\n\tif (typeof body !== \"string\") return body;\n\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\treturn parsed;\n\t} catch {\n\t\treturn body;\n\t}\n}\n\nfunction isWriteRequest(method: string | undefined) {\n\treturn method !== undefined && ![\"GET\", \"HEAD\"].includes(method.toUpperCase());\n}\n\nfunction isSapRequestPreview(request: ODataFetchRequestPreview) {\n\tconst baseUrl = request.baseUrl ?? \"odata\";\n\tif (baseUrl !== \"\") return true;\n\n\treturn request.path.startsWith(\"/sap/\") || request.path.startsWith(\"/sap-dp0/\");\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string) {\n\tconst normalizedName = name.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedName);\n}\n\nfunction setDefaultHeader(headers: Record<string, string>, name: string, value: string) {\n\tif (hasHeader(headers, name)) return;\n\theaders[name] = value;\n}\n\nfunction buildTransportHeadersPreview(request: ODataFetchRequestPreview) {\n\tconst headers = headersToRecord(request.init.headers);\n\tconst method = request.init.method;\n\tconst sapRequest = isSapRequestPreview(request);\n\n\tsetDefaultHeader(headers, \"DataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"MaxDataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"Accept\", \"application/json\");\n\n\theaders[\"sap-language\"] = \"ru\";\n\n\tif (sapRequest) {\n\t\theaders[\"sap-contextid-accept\"] = \"header\";\n\t}\n\n\tif (isWriteRequest(method) && request.init.body) {\n\t\tsetDefaultHeader(headers, \"Content-Type\", \"application/json\");\n\t}\n\n\tif (isWriteRequest(method) && sapRequest) {\n\t\tsetDefaultHeader(headers, \"x-csrf-token\", \"<получается отдельным GET перед реальным write-запросом>\");\n\t}\n\n\treturn headers;\n}\n\nfunction getTargetKind(target: ODataTargetMetadata) {\n\tif (isFunctionImportMetadata(target)) return \"FunctionImport\";\n\treturn target.result ? \"Parameterized Entity\" : \"Entity\";\n}\n\nfunction logObjectSection(title: string, value: unknown) {\n\tconst logger = getConsole();\n\tlogger.groupCollapsed(title);\n\tlogger.info(value);\n\tlogger.groupEnd();\n}\n\nfunction logODataDevRequest(info: ODataDevRequestLogInfo) {\n\tconst logger = getConsole();\n\tconst bodyPreview = parseRequestBodyForLog(info.request.init.body);\n\tconst initHeaders = headersToRecord(info.request.init.headers);\n\tconst transportHeaders = buildTransportHeadersPreview(info.request);\n\tconst requestInitPreview = {\n\t\tmethod: info.request.init.method,\n\t\theaders: initHeaders,\n\t\tbody: bodyPreview,\n\t\thasSignal: Boolean(info.request.init.signal)\n\t};\n\n\tlogger.groupCollapsed(`[OData DEV] ${info.requestMethod} ${info.request.fullUrl}`);\n\tlogger.table([\n\t\t{\n\t\t\thelper: info.helperName,\n\t\t\toperation: info.operation,\n\t\t\ttarget: info.odata.target,\n\t\t\ttargetKind: getTargetKind(info.target),\n\t\t\tservice: info.odata.service,\n\t\t\trealFetch: \"не выполнялся\"\n\t\t}\n\t]);\n\tlogger.info(\"Итоговый URL:\", info.request.fullUrl);\n\tlogger.info(\"Path без base URL:\", info.request.path);\n\tlogger.info(\"Target path до query options:\", info.targetPath);\n\tlogger.info(\"Query string:\", info.request.queryString || \"<пусто>\");\n\tlogger.info(\"Body:\", bodyPreview ?? \"<пусто>\");\n\tlogger.info(\"Auto parse:\", info.autoParse ?? false);\n\tlogger.info(\"Transform:\", info.hasTransform ? \"передан, но не вызывается без ответа backend\" : \"не передан\");\n\tlogger.info(\"Dry-run result:\", info.operation === \"query\" ? { data: [], totalCount: 0 } : { data: undefined });\n\tlogObjectSection(\"OData config\", info.odata);\n\tlogObjectSection(\"Target metadata\", info.target);\n\tlogObjectSection(\"Target params\", info.params);\n\tlogObjectSection(\"Query options\", info.queryOptions);\n\tlogObjectSection(\"RequestInit, переданный в transport\", requestInitPreview);\n\tlogObjectSection(\"Заголовки после transport defaults (без реального fetch)\", transportHeaders);\n\tlogger.groupEnd();\n}\n\nfunction notifyODataDevHelperCall(helperName: ODataDevHelperName) {\n\tnotify.warning(`${helperName}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, {\n\t\ttitle: \"OData DEV helper\"\n\t});\n}\n\nfunction createODataFetchFnDevRunner<I>(\n\tmethod: ODataOperationMethod,\n\topts: ODataFetchFnDevOptions<I>,\n\thelperName: ODataDevHelperName\n): ODataFetchFnRunner<unknown> {\n\tconst { odata, options = {}, init = {}, autoParse, swCache } = opts;\n\tconst params = opts.params ?? {};\n\n\treturn async ({ client, signal }: { client: QueryClient; signal?: AbortSignal }) => {\n\t\tnotifyODataDevHelperCall(helperName);\n\n\t\tconst baseUrl = resolveODataBaseUrl(odata.service, options.baseUrl);\n\t\tconst serviceMetadata = await getODataMetadataData({ service: odata.service, baseUrl }, client);\n\t\tif (!serviceMetadata) {\n\t\t\tthrow new Error(`Не удалось загрузить metadata OData-сервиса '${odata.service}'`);\n\t\t}\n\n\t\tconst target = resolveODataTarget(serviceMetadata, odata.target);\n\n\t\tvalidateODataOperation(target, method, odata);\n\n\t\tconst body = resolveRequestBody(opts.body, method);\n\t\tconst requestMethod = resolveRequestMethod(target, method);\n\t\tconst targetPath = buildTargetPath(target, odata, params, method);\n\n\t\tconst queryOptions = swCache ? { ...options, baseUrl, swCache } : { ...options, baseUrl };\n\t\tconst requestInit = { ...init, method: requestMethod, body, signal };\n\t\tconst request = buildODataFetchRequest(targetPath, queryOptions, requestInit);\n\n\t\tlogODataDevRequest({\n\t\t\thelperName,\n\t\t\toperation: method,\n\t\t\todata,\n\t\t\ttarget,\n\t\t\ttargetPath,\n\t\t\trequest,\n\t\t\trequestMethod,\n\t\t\tparams,\n\t\t\tqueryOptions,\n\t\t\tbody,\n\t\t\tautoParse,\n\t\t\thasTransform: Boolean(opts.transform)\n\t\t});\n\n\t\tif (method === \"query\") {\n\t\t\treturn { data: [], totalCount: 0 };\n\t\t}\n\n\t\treturn { data: undefined };\n\t};\n}\n\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }): ODataFetchFnRunner<O[]>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, I, P> & { transform?: undefined }): ODataFetchFnRunner<I[]>;\nexport function odataFetchFnDev<\n\tI,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataSingleOperationMethod = ODataSingleOperationMethod\n>(method: M, opts: ODataSingleFetchFnRequest<M, I, I, T, P> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataFetchFnDev<I, O = I, T = I, M extends ODataSingleOperationMethod = ODataSingleOperationMethod>(\n\tmethod: M,\n\topts: ODataSingleFetchFnRequest<M, I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataOperationMethod = ODataOperationMethod\n>(method: M, opts: ODataFetchFnRequest<M, I, O, T, P>): ODataFetchFnRunner<unknown>;\nexport function odataFetchFnDev(...args: ODataFetchFnImplementationArgs): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\tswitch (args[0]) {\n\t\t\tcase \"create\": {\n\t\t\t\treturn odataFetchFn(\"create\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\treturn odataFetchFn(\"update\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"delete\": {\n\t\t\t\treturn odataFetchFn(\"delete\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"read\": {\n\t\t\t\treturn odataFetchFn(\"read\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"query\": {\n\t\t\t\treturn odataFetchFn(\"query\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"fi\": {\n\t\t\t\treturn odataFetchFn(\"fi\", args[1]);\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst checker: never = args[0];\n\t\t\t\tvoid checker;\n\n\t\t\t\tthrow new Error(\"Неподдерживаемая OData operation в odataFetchFnDev\");\n\t\t\t}\n\t\t}\n\t}\n\n\tconst [method, opts] = args;\n\treturn createODataFetchFnDevRunner(method, opts, \"odataFetchFnDev\");\n}\n\nexport function odataCreateFnDev<I, T = I>(opts: ODataCreateFnOptions<I, I, T> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataCreateFnDev<I, O = I, T = I>(\n\topts: ODataCreateFnOptions<I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataCreateFnDev<I, O = I, T = I>(opts: ODataCreateFnOptions<I, O, T>): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, never, \"create\">(\"create\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"create\", opts, \"odataCreateFnDev\");\n}\n\nexport function odataUpdateFnDev<I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, I, T, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, P, \"update\">(\"update\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"update\", opts, \"odataUpdateFnDev\");\n}\n\nexport function odataDeleteFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"delete\">(\"delete\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"delete\", opts, \"odataDeleteFnDev\");\n}\n\nexport function odataReadFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"read\">(\"read\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"read\", opts, \"odataReadFnDev\");\n}\n\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }\n): ODataFetchFnRunner<O[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform?: undefined }\n): ODataFetchFnRunner<I[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, void, P, \"query\">(\"query\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"query\", opts, \"odataQueryFnDev\");\n}\n\nexport function odataFunctionImportFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"fi\">(\"fi\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"fi\", opts, \"odataFunctionImportFnDev\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/odata/createODataCollectionQueryKey.ts","../../src/odata/flattenODataDependentServices.ts","../../src/odata/sortODataDependentSegmentItemsByChains.ts","../../src/odata/sortODataDependentServicesByChains.ts","../../src/odata/fetchCollectionData.ts","../../src/odata/projectODataCollectionSort.ts","../../src/odata/useODataCollectionUpdatesQuery.ts","../../src/odata/useODataMetadata.ts","../../src/odata/useODataEntity.ts","../../src/odata/useODataCollectionQuery.ts","../../src/odata/useODataCollection.ts","../../src/odata/useODataCollectionChains.ts","../../src/odata/useODataCollectionModel.ts","../../src/odata/useODataTableColumns.ts","../../src/odata/odataFetchFnDev.ts"],"sourcesContent":["import { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\n/**\n * Версия формы persisted collection snapshot.\n *\n * Версия 2 отделяет прежние записи, порядок `separated` которых зависел от\n * первого consumer, от новой канонической сортировки по code.\n */\nconst ODATA_COLLECTION_QUERY_VERSION = 2;\n\nexport const createODataCollectionBaseQueryKey = () => [...odataBaseQueryKey, \"collection\"] as const;\n\nexport const createODataCollectionQueryKey = ({ service, target, limitedKeys, serverFilter }: ODataServiceCollectionConfig) =>\n\t[\n\t\t...createODataCollectionBaseQueryKey(),\n\t\t{ version: ODATA_COLLECTION_QUERY_VERSION, service, target, limitedKeys, serverFilter }\n\t] as const;\n","import type { ODataDependentBaseProps, ODataDependentSegmentItem } from \"./types\";\n\n/**\n * Разворачивает зависимые OData-сервисы в плоский список segment-level элементов.\n */\nexport function flattenODataDependentServices(services: readonly ODataDependentBaseProps[]): ODataDependentSegmentItem[] {\n\tconst out: ODataDependentSegmentItem[] = [];\n\n\tfor (const [serviceIndex, service] of services.entries()) {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\n\t\tfor (const [segmentIndex, [id, segment]] of Object.entries(service.segments).entries()) {\n\t\t\tout.push({\n\t\t\t\tid,\n\t\t\t\tserviceKey,\n\t\t\t\tserviceIndex,\n\t\t\t\tsegmentIndex,\n\t\t\t\todata: service.odata,\n\t\t\t\tsegment,\n\t\t\t\tmodel: {\n\t\t\t\t\t...service.model,\n\t\t\t\t\tcodeKey: id\n\t\t\t\t},\n\t\t\t\tpanelVisibility: segment.panelVisibility ?? \"user\"\n\t\t\t});\n\t\t}\n\t}\n\n\treturn out;\n}\n","import { ODataDependentSegmentItem } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Сортирует плоские segment-level элементы по chain-порядку\n * и опционально накладывает пользовательский override.\n */\nexport function sortODataDependentSegmentItemsByChains(\n\titems: readonly ODataDependentSegmentItem[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentSegmentItem[] {\n\tconst chainOrderByService = new Map<string, Map<string, number>>();\n\n\tfor (const [serviceKey, chain] of Object.entries(chains)) {\n\t\tchainOrderByService.set(serviceKey, new Map(chain.map((item, index) => [item.codeKey, index])));\n\t}\n\n\tconst baseOrdered = [...items]\n\t\t.map((item, index) => ({\n\t\t\titem,\n\t\t\tindex\n\t\t}))\n\t\t.sort((left, right) => {\n\t\t\tif (left.item.serviceIndex !== right.item.serviceIndex) {\n\t\t\t\treturn left.item.serviceIndex - right.item.serviceIndex;\n\t\t\t}\n\n\t\t\tconst chainOrder = chainOrderByService.get(left.item.serviceKey);\n\t\t\tconst leftChainOrder = chainOrder?.get(left.item.id);\n\t\t\tconst rightChainOrder = chainOrder?.get(right.item.id);\n\n\t\t\tif (leftChainOrder !== undefined && rightChainOrder !== undefined) {\n\t\t\t\treturn leftChainOrder - rightChainOrder;\n\t\t\t}\n\t\t\tif (leftChainOrder !== undefined) return -1;\n\t\t\tif (rightChainOrder !== undefined) return 1;\n\n\t\t\tif (left.item.segmentIndex !== right.item.segmentIndex) {\n\t\t\t\treturn left.item.segmentIndex - right.item.segmentIndex;\n\t\t\t}\n\n\t\t\treturn left.index - right.index;\n\t\t});\n\n\tif (!orderOverrideIds?.length) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst availableIds = new Set(baseOrdered.map(({ item }) => item.id));\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => availableIds.has(id));\n\tif (normalizedOverride.length === 0) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\n\treturn [...baseOrdered]\n\t\t.sort((left, right) => {\n\t\t\tconst leftOverrideRank = overrideRank.get(left.item.id);\n\t\t\tconst rightOverrideRank = overrideRank.get(right.item.id);\n\n\t\t\tif (leftOverrideRank !== undefined && rightOverrideRank !== undefined) {\n\t\t\t\treturn leftOverrideRank - rightOverrideRank;\n\t\t\t}\n\t\t\tif (leftOverrideRank !== undefined) return -1;\n\t\t\tif (rightOverrideRank !== undefined) return 1;\n\n\t\t\treturn left.index - right.index;\n\t\t})\n\t\t.map(({ item }) => item);\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport { ODataDependentBaseProps } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Применяет пользовательский override порядка сегментов поверх уже рассчитанного базового порядка.\n *\n * Алгоритм:\n * 1. берёт только валидные id из `orderOverrideIds` (без дублей);\n * 2. поднимает эти id в начало в указанной последовательности;\n * 3. все остальные сегменты оставляет в исходном относительном порядке.\n */\nfunction applySegmentsOrderOverride(\n\tservices: readonly ODataDependentBaseProps[],\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tif (!orderOverrideIds?.length) return [...services];\n\n\tconst visibleIds = new Set<string>();\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tvisibleIds.add(segmentId);\n\t\t}\n\t}\n\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => visibleIds.has(id));\n\tif (normalizedOverride.length === 0) return [...services];\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\tconst fallbackRankStart = normalizedOverride.length;\n\tconst segmentRank = new Map<string, number>();\n\tlet fallbackRank = fallbackRankStart;\n\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tif (segmentRank.has(segmentId)) continue;\n\t\t\tsegmentRank.set(segmentId, overrideRank.get(segmentId) ?? fallbackRank++);\n\t\t}\n\t}\n\n\tconst withOrderedSegments = services.map((service) => {\n\t\tconst orderedEntries = Object.entries(service.segments).sort(\n\t\t\t([leftId], [rightId]) =>\n\t\t\t\t(segmentRank.get(leftId) ?? Number.MAX_SAFE_INTEGER) - (segmentRank.get(rightId) ?? Number.MAX_SAFE_INTEGER)\n\t\t);\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn [...withOrderedSegments].sort((leftService, rightService) => {\n\t\tconst leftFirstSegmentId = Object.keys(leftService.segments)[0];\n\t\tconst rightFirstSegmentId = Object.keys(rightService.segments)[0];\n\t\tconst leftRank = leftFirstSegmentId ? (segmentRank.get(leftFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\t\tconst rightRank = rightFirstSegmentId ? (segmentRank.get(rightFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\n\t\treturn leftRank - rightRank;\n\t});\n}\n\n/**\n * Сортирует сегменты сервисов по chain-порядку (от меньшего к большему)\n * и опционально накладывает пользовательский override.\n *\n * Если chain недоступен, сохраняет исходный порядок сегментов.\n *\n * @deprecated функционал должен быть вырезан и оставлен только с `sortODataDependentSegmentItemsByChains`\n */\nexport function sortODataDependentServicesByChains(\n\tservices: readonly ODataDependentBaseProps[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tconst sortedByChains = services.map((service) => {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\t\tconst chain = chains[serviceKey];\n\t\tif (!chain?.length) return service;\n\n\t\tconst chainOrder = new Map(chain.map((item, index) => [item.codeKey, index]));\n\t\tconst orderedEntries = Object.entries(service.segments).sort(([leftId], [rightId]) => {\n\t\t\tconst leftOrder = chainOrder.get(leftId);\n\t\t\tconst rightOrder = chainOrder.get(rightId);\n\n\t\t\tif (leftOrder !== undefined && rightOrder !== undefined) return leftOrder - rightOrder;\n\t\t\tif (leftOrder !== undefined) return -1;\n\t\t\tif (rightOrder !== undefined) return 1;\n\t\t\treturn compareStrings(leftId, rightId);\n\t\t});\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn applySegmentsOrderOverride(sortedByChains, orderOverrideIds);\n}\n","import { type CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { logError } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { odataFetch, type ODataFetchOptions } from \"./odataFetch\";\nimport { isNoContentResponse } from \"./transport\";\n\n// Тип для результата запроса справочника\ninterface ODataServiceResult<T extends CollectionItem> {\n\titems: T[];\n}\n\n/**\n * Загрузка данных справочника из OData сервиса\n */\nexport async function fetchCollectionData<T extends CollectionItem>(params: {\n\turl: string;\n\tquery?: ODataFetchOptions<T>;\n\tsignal: AbortSignal;\n}): Promise<ODataServiceResult<T>> {\n\tconst { url, query, signal } = params;\n\n\ttry {\n\t\t// Загружаем данные из OData сервиса\n\t\tconst response = await odataFetch<T, T[]>(url, query, { signal });\n\n\t\t// Считаем отсутствие данных ошибкой, ведь query запрос обязан вернуть корректное тело json\n\t\tif (isNoContentResponse(response)) {\n\t\t\tthrow new Error(\"отсутствует тело ответа\");\n\t\t}\n\n\t\tconst data = response.data;\n\n\t\t// Удаление ненужных полей.\n\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars\n\t\t\titems: data.map(({ ID, CNT, __metadata, __Parameters, ...item }) => item as T) /*, pairs, pairsMap */\n\t\t};\n\t} catch (error) {\n\t\tlogError(\"Ошибка загрузки справочника:\", error);\n\t\t// throw error;\n\n\t\treturn { items: [] };\n\t}\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport type { ODataCollectionResult } from \"./useODataCollectionQuery\";\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\n/**\n * Создаёт observer-проекцию канонического справочника с сортировкой по text.\n *\n * Query cache и persistence продолжают хранить один code-sorted snapshot.\n * Проекция копирует только массивы ссылок в `separated`: исходные строки,\n * объекты элементов, `items`, `chain` и metadata остаются общими.\n */\nexport function projectODataCollectionSortByText<T extends CollectionItem>(source: ODataCollectionResult<T>): ODataCollectionResult<T> {\n\tlet hasProjectedLevel = false;\n\tconst separated = Object.fromEntries(\n\t\tObject.entries(source.separated).map(([codeKey, items]) => {\n\t\t\tconst textKey = source.keyPairsMap[codeKey];\n\t\t\tif (!textKey || items.length < 2) {\n\t\t\t\treturn [codeKey, items];\n\t\t\t}\n\n\t\t\thasProjectedLevel = true;\n\t\t\treturn [codeKey, [...items].sort((left, right) => compareStrings(String(left[textKey] ?? \"\"), String(right[textKey] ?? \"\")))];\n\t\t})\n\t) as Record<string, T[]>;\n\n\tif (!hasProjectedLevel) {\n\t\treturn source;\n\t}\n\n\treturn {\n\t\t...source,\n\t\tseparated\n\t};\n}\n","import { parseDate } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { queryOptions, useQuery } from \"@tanstack/react-query\";\n\nimport { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { odataFetch } from \"./odataFetch\";\nimport { getODataProjectAdapter, resolveODataBaseUrl } from \"./odataProjectAdapter\";\n\nconst COLLECTION_UPDATES_BUILD_ID = __APP_BUILD_ID__;\nconst COLLECTION_UPDATES_STALE_TIME = 1000 * 60 * 60 * 4;\nexport const ODATA_COLLECTION_UPDATES_LOOKBACK_MS = 1000 * 60 * 60 * 24 * 7;\nexport const ODATA_COLLECTION_DEFAULT_SW_CACHE = \"ttl=forever;name=ref\";\nexport const ODATA_COLLECTION_BUST_SW_CACHE = \"bust=forever;name=ref\";\nexport const ODATA_COLLECTION_UPDATES_SW_CACHE = \"ttl=4h;name=ref-updates\";\n\ninterface ODataCollectionUpdateRecord {\n\tentityName: string;\n\tlastChanged: string;\n}\n\nexport interface ODataCollectionUpdateItem extends ODataCollectionUpdateRecord {\n\tlastChangedAt: Date | null;\n}\n\nexport interface ODataCollectionUpdatesResult {\n\titems: ODataCollectionUpdateItem[];\n\tbyEntityName: Record<string, ODataCollectionUpdateItem>;\n\tfetchedAt: number;\n\tcoverageStartedAt: number;\n}\n\nexport interface ODataCollectionUpdatesOptions {\n\tstaleTime?: number;\n}\n\nexport const createODataCollectionUpdatesQueryKey = () =>\n\t[...odataBaseQueryKey, \"collection-updates\", { buildId: COLLECTION_UPDATES_BUILD_ID }] as const;\n\nfunction normalizeCollectionUpdateRecord(record: ODataCollectionUpdateRecord): ODataCollectionUpdateItem {\n\treturn {\n\t\t...record,\n\t\tlastChangedAt: parseDate(record.lastChanged)\n\t};\n}\n\nfunction normalizeCollectionUpdates(records: ODataCollectionUpdateRecord[], fetchedAt: number): ODataCollectionUpdatesResult {\n\tconst items = records.map(normalizeCollectionUpdateRecord);\n\tconst byEntityName = items.reduce<Record<string, ODataCollectionUpdateItem>>((acc, item) => {\n\t\tif (item.entityName) {\n\t\t\tacc[item.entityName] = item;\n\t\t}\n\n\t\treturn acc;\n\t}, {});\n\n\treturn { items, byEntityName, fetchedAt, coverageStartedAt: fetchedAt - ODATA_COLLECTION_UPDATES_LOOKBACK_MS };\n}\n\n/**\n * Загружает компактный список справочников, изменённых за последние 7 дней.\n * Сам список живёт отдельно от данных справочников и управляет их точечной инвалидацией.\n */\nexport function fetchODataCollectionUpdates() {\n\treturn async ({ signal }: { signal: AbortSignal }): Promise<ODataCollectionUpdatesResult> => {\n\t\tconst requestStartedAt = Date.now();\n\t\tconst endpoint = getODataProjectAdapter().collectionUpdates;\n\t\tif (!endpoint) return normalizeCollectionUpdates([], requestStartedAt);\n\n\t\tconst response = await odataFetch<ODataCollectionUpdateRecord, ODataCollectionUpdateRecord[]>(\n\t\t\t`/${endpoint.service}/${endpoint.target}`,\n\t\t\t{\n\t\t\t\tbaseUrl: resolveODataBaseUrl(endpoint.service, endpoint.baseUrl),\n\t\t\t\tswCache: ODATA_COLLECTION_UPDATES_SW_CACHE\n\t\t\t},\n\t\t\t{ signal }\n\t\t);\n\n\t\treturn normalizeCollectionUpdates(response.data, Math.max(requestStartedAt, Date.now()));\n\t};\n}\n\n/**\n * Описывает общий TanStack Query со списком обновлённых справочников.\n * Query сохраняется в IndexedDB и дополнительно кешируется Service Worker на короткий TTL.\n *\n * При отсутствии endpoint queryFn возвращает пустой успешный результат без сетевого запроса.\n * Query должен оставаться активным, потому что зависимые справочники ждут его завершения.\n */\nexport const odataCollectionUpdatesQueryOptions = (options: ODataCollectionUpdatesOptions = {}) =>\n\tqueryOptions({\n\t\tqueryKey: createODataCollectionUpdatesQueryKey(),\n\t\tqueryFn: fetchODataCollectionUpdates(),\n\t\tmeta: persistedQueryMeta,\n\t\tstaleTime: options.staleTime ?? COLLECTION_UPDATES_STALE_TIME,\n\t\tgcTime: Infinity\n\t});\n\nexport function useODataCollectionUpdatesQuery(options: ODataCollectionUpdatesOptions = {}) {\n\treturn useQuery(odataCollectionUpdatesQueryOptions(options));\n}\n","import { useODataMetadataQuery } from \"./useODataMetadataQuery\";\n\nimport type { ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Возвращает metadata конкретной OData-сущности по имени сервиса и сущности.\n *\n * Хук не добавляет собственную бизнес-логику и служит публичной тонкой\n * прослойкой над `useODataMetadataQuery(...)`.\n */\nexport function useODataMetadata(odata: ODataServiceConfig) {\n\tconst { data, dataUpdatedAt = 0, isLoading, isLoadingError } = useODataMetadataQuery({ service: odata.service });\n\tconst metadata = data?.entities[odata.target];\n\n\tif (!isLoading && !metadata && data?.functionImports[odata.target]) {\n\t\tthrow new Error(`OData target '${odata.target}' является FunctionImport и не может использоваться как сущность`);\n\t}\n\n\tif (isLoadingError) {\n\t\tthrow new Error(`Ошибка загрузки метаданных сервиса ${odata.service}`);\n\t}\n\n\treturn { metadata, metadataUpdatedAt: dataUpdatedAt, isLoading };\n}\n","import { useMemo } from \"react\";\n\nimport { buildEntityPath, type ODataServiceConfig, type ODataValue } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nconst throwErrorText = \"Использование actions недопустимо до окончания загрузки metadata\";\n\n// function throwNoMetadata() {\n// \tif (__DEV__) {\n// \t\tthrow new Error(throwErrorText);\n// \t}\n// \treturn undefined;\n// }\n\nexport type ODataEntity = Omit<ReturnType<typeof useODataEntity>, \"isLoading\">;\n\nexport function useODataEntity(odata: ODataServiceConfig) {\n\tconst { metadata, metadataUpdatedAt, isLoading } = useODataMetadata(odata);\n\n\tconst actions = useMemo(() => {\n\t\tconst getEntityPath = (values: Record<string, ODataValue> = {}) => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn buildEntityPath(metadata, odata, values);\n\t\t};\n\t\tconst getKeys = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns?.map((c) => c.id);\n\t\t};\n\t\tconst getKeyPairs = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns\n\t\t\t\t?.filter((c) => c.semanticType === \"code\" && c.linkedColumnId)\n\t\t\t\t.map((c) => ({ codeKey: c.id, textKey: c.linkedColumnId }) as CollectionPair);\n\t\t};\n\t\tconst getKeyPairsMap = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\tconst pairs: Record<string, string> = {};\n\n\t\t\tfor (const column of metadata.columns ?? []) {\n\t\t\t\tif (column.semanticType === \"code\" && column.linkedColumnId) {\n\t\t\t\t\tpairs[column.id] = column.linkedColumnId;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn pairs;\n\t\t};\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Получить строку запроса `/service/entity(parameters)/Results`\n\t\t\t */\n\t\t\tgetEntityPath,\n\t\t\t/**\n\t\t\t * Получить все ключи сущности\n\t\t\t */\n\t\t\tgetKeys,\n\t\t\t/**\n\t\t\t * Получить список ключей в формате `{ codeKey, textKey }`\n\t\t\t */\n\t\t\tgetKeyPairs,\n\t\t\t/**\n\t\t\t * Получить словать ключей в формате `{ code: text }`\n\t\t\t */\n\t\t\tgetKeyPairsMap\n\t\t};\n\t}, [odata, metadata]);\n\n\treturn { config: odata, metadata, metadataUpdatedAt, isLoading, actions };\n}\n","import { useEffect, useMemo } from \"react\";\n\nimport { buildSeparatedArrays, type CollectionItem, type CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { useQuery, useQueryClient, UseQueryResult } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { fetchCollectionData } from \"./fetchCollectionData\";\nimport { projectODataCollectionSortByText } from \"./projectODataCollectionSort\";\nimport { ODataCollectionConfig } from \"./types\";\nimport {\n\tODATA_COLLECTION_BUST_SW_CACHE,\n\tODATA_COLLECTION_DEFAULT_SW_CACHE,\n\tODataCollectionUpdateItem,\n\tuseODataCollectionUpdatesQuery\n} from \"./useODataCollectionUpdatesQuery\";\nimport { useODataEntity } from \"./useODataEntity\";\n\nexport interface ODataCollectionResult<T extends CollectionItem> {\n\titems: T[];\n\tkeyPairs: CollectionPair[];\n\tkeyPairsMap: Record<string, string>;\n\t/**\n\t * Массивы элементов по уровням справочника.\n\t *\n\t * Query cache хранит канонический порядок по code, а конкретный observer\n\t * может получить проекцию по text. Один snapshot при этом переиспользуется\n\t * ракурсами с разными `sortByCode`.\n\t */\n\tseparated: Record<string, T[]>;\n\tchain: { codeKey: string; count: number }[];\n\tcount: number;\n\tcacheUpdatedAt: number;\n}\n\ninterface ODataCollectionCacheRefreshContext {\n\tupdate?: ODataCollectionUpdateItem;\n\tmetadataUpdatedAt?: number;\n\tupdatesCoverageStartedAt?: number;\n}\n\nexport function resolveODataCollectionSwCachePolicy(swCache: string, shouldBust: boolean) {\n\tif (!shouldBust) return swCache;\n\n\tconst normalized = swCache.trim().toLowerCase();\n\tif (normalized === \"off\" || normalized.startsWith(\"bust=\")) return swCache;\n\tif (normalized.startsWith(\"ttl=\")) return swCache.replace(/^\\s*ttl=/i, \"bust=\");\n\n\treturn ODATA_COLLECTION_BUST_SW_CACHE;\n}\n\nfunction isUsableTimestamp(value: number | undefined): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Определяет, нужно ли обновить конкретный справочник по списку изменений.\n * Сравнение идёт с cacheUpdatedAt, который сохраняется вместе с данными справочника.\n */\nexport function shouldRefreshODataCollectionCache<T extends CollectionItem>(\n\tcontext: ODataCollectionCacheRefreshContext,\n\tcachedData: ODataCollectionResult<T> | undefined\n) {\n\tconst cacheUpdatedAt = cachedData?.cacheUpdatedAt ?? 0;\n\tconst updateChangedAt = context.update?.lastChangedAt?.getTime();\n\n\tif (isUsableTimestamp(updateChangedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (updateChangedAt > cacheUpdatedAt) return true;\n\t}\n\n\tif (isUsableTimestamp(context.metadataUpdatedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (context.metadataUpdatedAt > cacheUpdatedAt) return true;\n\t}\n\n\t/**\n\t * Бэкенд отдаёт список изменений справочников только за последнюю неделю.\n\t * Если локальный справочник старше этого окна, отсутствие target в списке\n\t * больше не доказывает актуальность, поэтому обновляем только открытый справочник.\n\t */\n\tif (isUsableTimestamp(context.updatesCoverageStartedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (cacheUpdatedAt < context.updatesCoverageStartedAt) return true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Универсальный хук для получения данных из OData сервиса.\n * Заменяет функционал TextDataService из SAP UI5.\n */\nexport function useODataCollectionQuery<T extends CollectionItem>(odata: ODataCollectionConfig): UseQueryResult<ODataCollectionResult<T>> {\n\tconst {\n\t\tservice,\n\t\ttarget,\n\t\tlimitedKeys,\n\t\texcludeEmpty,\n\t\tsortByCode,\n\t\tserverFilter,\n\t\tclientFilter,\n\t\tswCache = ODATA_COLLECTION_DEFAULT_SW_CACHE\n\t} = odata;\n\tconst queryClient = useQueryClient();\n\tconst { actions, metadata, metadataUpdatedAt, isLoading } = useODataEntity(odata);\n\tconst updatesQuery = useODataCollectionUpdatesQuery();\n\n\tconst queryKey = useMemo(\n\t\t() => createODataCollectionQueryKey({ service, target, limitedKeys, serverFilter }),\n\t\t[service, target, limitedKeys, serverFilter]\n\t);\n\tconst cachedData = queryClient.getQueryData<ODataCollectionResult<T>>(queryKey);\n\tconst collectionUpdate = updatesQuery.data?.byEntityName[target];\n\tconst shouldBustCollectionCache = shouldRefreshODataCollectionCache(\n\t\t{\n\t\t\tupdate: collectionUpdate,\n\t\t\tmetadataUpdatedAt,\n\t\t\tupdatesCoverageStartedAt: updatesQuery.data?.coverageStartedAt\n\t\t},\n\t\tcachedData\n\t);\n\tconst effectiveSwCache = resolveODataCollectionSwCachePolicy(swCache, shouldBustCollectionCache);\n\tconst updatesReady = updatesQuery.isError || (updatesQuery.isSuccess && !updatesQuery.isFetching);\n\n\tuseEffect(() => {\n\t\tif (!cachedData || !shouldBustCollectionCache) return;\n\n\t\tvoid queryClient.invalidateQueries({ queryKey });\n\t}, [cachedData, queryClient, queryKey, shouldBustCollectionCache]);\n\n\treturn useQuery({\n\t\tqueryKey,\n\t\tqueryFn: async ({ signal }) => {\n\t\t\tconst requestStartedAt = Date.now();\n\t\t\tconst selectKeys = limitedKeys ? [...limitedKeys] : actions.getKeys();\n\t\t\tconst keyPairs = actions.getKeyPairs();\n\t\t\tconst keyPairsMap = actions.getKeyPairsMap();\n\n\t\t\tif (limitedKeys) {\n\t\t\t\tfor (const k of limitedKeys) {\n\t\t\t\t\tconst keyText = keyPairsMap[k];\n\t\t\t\t\tif (keyText && !selectKeys.includes(keyText)) {\n\t\t\t\t\t\tselectKeys.push(keyText);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { items } = await fetchCollectionData<T>({\n\t\t\t\turl: `/${service}/${target}`,\n\t\t\t\tquery: {\n\t\t\t\t\tselect: selectKeys,\n\t\t\t\t\texpression: serverFilter,\n\t\t\t\t\tswCache: effectiveSwCache\n\t\t\t\t},\n\t\t\t\tsignal\n\t\t\t});\n\n\t\t\tlet filterdItems = items;\n\t\t\tif (clientFilter) {\n\t\t\t\tfilterdItems = items.filter(clientFilter);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Query cache хранит единую каноническую проекцию справочника.\n\t\t\t *\n\t\t\t * Сортировка конкретного контрола применяется observer-проекцией ниже,\n\t\t\t * чтобы два ракурса с разными `sortByCode` переиспользовали один snapshot,\n\t\t\t * а не конкурировали за его порядок и не дублировали всю коллекцию в памяти.\n\t\t\t */\n\t\t\tconst separated = buildSeparatedArrays<T>(filterdItems, keyPairs, excludeEmpty, true);\n\n\t\t\t// Рассчитать порядок от меньшего к большему\n\t\t\tconst chain = keyPairs\n\t\t\t\t.map((pair) => ({ codeKey: pair.codeKey, count: separated[pair.codeKey].length }))\n\t\t\t\t.sort((a, b) => a.count - b.count);\n\n\t\t\treturn {\n\t\t\t\titems: filterdItems,\n\t\t\t\tkeyPairs,\n\t\t\t\tkeyPairsMap,\n\t\t\t\tseparated,\n\t\t\t\tchain,\n\t\t\t\tcount: filterdItems.length,\n\t\t\t\tcacheUpdatedAt: Math.max(requestStartedAt, Date.now(), collectionUpdate?.lastChangedAt?.getTime() ?? 0, metadataUpdatedAt)\n\t\t\t};\n\t\t},\n\t\tenabled: Boolean(!isLoading && metadata && service && target && updatesReady),\n\t\tmeta: persistedQueryMeta,\n\t\t/**\n\t\t * Клиентский кеш можно держать не долго, чтобы он мог чаще дергать SW\n\t\t */\n\t\tstaleTime: 1000 * 60 * 60 * 2,\n\t\t/**\n\t\t * Если справочник не используется более часа, то можно из памяти выгрузить.\n\t\t */\n\t\tgcTime: 1000 * 60 * 60 * 1,\n\t\t/**\n\t\t * Сортировка является представлением observer, а не identity Query.\n\t\t * TanStack мемоизирует select-проекцию и не сохраняет её в общий cache.\n\t\t */\n\t\tselect: sortByCode === false ? projectODataCollectionSortByText<T> : undefined\n\t});\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\n\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataCollectionConfig, ODataCollectionModel } from \"./types\";\nimport { useODataCollectionQuery } from \"./useODataCollectionQuery\";\n\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\ninterface UseODataCollectionProps {\n\todata: ODataCollectionConfig;\n\tmodel: Required<ODataCollectionModel>;\n\n\t/**\n\t * Размер страницы для виртуализации.\n\t */\n\tpageSize?: number;\n\n\tfilter?: (item: CollectionItem) => boolean;\n}\n\nexport function useODataCollection({\n\todata,\n\tmodel,\n\t// filter,\n\tpageSize = 50\n}: UseODataCollectionProps) {\n\tconst { codeKey, maxVisibleItems } = model;\n\tconst { data: rawData, isLoading, isError, refetch } = useODataCollectionQuery(odata);\n\n\tconst textKey = rawData?.keyPairsMap[codeKey] ?? \"\";\n\n\t// Клиент для инвалидации запросов\n\tconst queryClient = useQueryClient();\n\n\tconst [filteredKeys, setFilteredKeys] = useState<Set<string>>();\n\n\tconst debounceTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n\t/**\n\t * itemsMap - индекс элементов для быстрого поиска\n\t * orderedKeys - упорядоченный список ключей для сохранения порядка\n\t */\n\tconst { itemsMap, separatedItems, orderedKeys } = useMemo(() => {\n\t\tconst itemsMap = new Map<string, CollectionItem>();\n\t\tconst orderedKeys = [] as string[];\n\t\tlet separatedItems: CollectionItem[] = [];\n\n\t\tif (rawData && rawData.separated[codeKey]) {\n\t\t\tseparatedItems = rawData.separated[codeKey];\n\n\t\t\tfor (const item of separatedItems) {\n\t\t\t\tconst key = item[codeKey];\n\t\t\t\tif (key) {\n\t\t\t\t\titemsMap.set(key, item);\n\t\t\t\t\torderedKeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { itemsMap, separatedItems, orderedKeys };\n\t}, [rawData, codeKey]);\n\n\t// Создание индекса поиска для текстовых полей\n\tconst buildSearchIndex = useCallback(\n\t\t(field: string) => {\n\t\t\tconst items = rawData?.separated[codeKey];\n\n\t\t\tif (!items) {\n\t\t\t\treturn new Map<string, Set<string>>();\n\t\t\t}\n\n\t\t\tconst index = new Map<string, Set<string>>();\n\n\t\t\t// Создаем индекс по префиксам для быстрого поиска\n\t\t\tfor (const item of items) {\n\t\t\t\tconst value = item[field]?.toLowerCase();\n\t\t\t\tif (!value) continue;\n\n\t\t\t\t// Индексируем по префиксам длиной 1-5 символов\n\t\t\t\tfor (let i = 1; i <= Math.min(5, value.length); i++) {\n\t\t\t\t\tconst prefix = value.substring(0, i);\n\t\t\t\t\tif (!index.has(prefix)) {\n\t\t\t\t\t\tindex.set(prefix, new Set<string>());\n\t\t\t\t\t}\n\t\t\t\t\tindex.get(prefix)!.add(item[codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn index;\n\t\t},\n\t\t[rawData, codeKey]\n\t);\n\n\t/**\n\t * Устанавливает несколько фильтров зависимостей.\n\t *\n\t * Сформированный список ключей пойдёт в фильтрацию элементов текущей коллекции по `codeKey`\n\t */\n\tconst setFilteredItems = useCallback(\n\t\t(filters: CollectionItem[] | undefined) => {\n\t\t\tsetFilteredKeys(() => {\n\t\t\t\tif (filters?.length) {\n\t\t\t\t\treturn new Set(filters.map((item) => item[codeKey]));\n\t\t\t\t}\n\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t},\n\t\t[codeKey]\n\t);\n\n\tconst getItems = useCallback(\n\t\t(\n\t\t\tpredicate?: (codeValue: string, textValue: string) => boolean,\n\t\t\tcurrentSelectedKeys?: readonly CollectionItem[]\n\t\t): CollectionItem[] => {\n\t\t\tif (!orderedKeys.length) return [];\n\n\t\t\tconst limit = maxVisibleItems;\n\t\t\tconst selectedKeysSet = new Set<string>();\n\t\t\tconst resultItems: CollectionItem[] = [];\n\n\t\t\tif (currentSelectedKeys?.length) {\n\t\t\t\t// Быстрое заполнение Set без создания временного массива\n\t\t\t\tfor (let i = 0; i < currentSelectedKeys.length; i++) {\n\t\t\t\t\tselectedKeysSet.add(currentSelectedKeys[i][codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet count = 0;\n\n\t\t\tconst existsDependencies = filteredKeys && filteredKeys.size > 0;\n\n\t\t\t// Единый проход с ранним выходом по лимиту\n\t\t\tfor (const key of orderedKeys) {\n\t\t\t\tif (count >= limit) break;\n\n\t\t\t\tconst item = itemsMap.get(key);\n\t\t\t\tif (!item) continue;\n\n\t\t\t\t// Проверка на исключение выбранных ключей\n\t\t\t\tif (selectedKeysSet.size > 0 && selectedKeysSet.has(key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst itemCode = item[codeKey];\n\n\t\t\t\tif (existsDependencies && !filteredKeys.has(itemCode)) continue;\n\n\t\t\t\t// Проверка внешнего предиката\n\t\t\t\tif (predicate && !predicate(itemCode, item[textKey])) continue;\n\n\t\t\t\tresultItems.push(item);\n\t\t\t\tcount++;\n\t\t\t}\n\n\t\t\treturn resultItems;\n\t\t},\n\t\t[orderedKeys, maxVisibleItems, codeKey, itemsMap, filteredKeys, textKey]\n\t);\n\n\t/**\n\t * Получает страницу данных для виртуализации.\n\t */\n\tconst getPage = useCallback(\n\t\t(pageIndex: number): CollectionItem[] => {\n\t\t\tconst allItems = rawData?.separated[codeKey] || [];\n\t\t\tconst start = pageIndex * pageSize;\n\t\t\tconst end = start + pageSize;\n\t\t\treturn allItems.slice(start, end);\n\t\t},\n\t\t[rawData, pageSize, codeKey]\n\t);\n\n\t/**\n\t * Находит несколько элементов по ключам.\n\t */\n\tconst findSourceItemsByKeys = useCallback(\n\t\t(key: string, keys: string[]) => {\n\t\t\tif (!rawData) return [];\n\n\t\t\tconst keysSet = new Set<string>(keys);\n\t\t\treturn rawData.items.filter((item) => keysSet.has(item[key]));\n\t\t},\n\t\t[rawData]\n\t);\n\n\t/**\n\t * Дебаунсинг для частых операций.\n\t */\n\tconst debounce = useCallback((key: string, fn: () => void, delay: number = 200) => {\n\t\t// Очищаем предыдущий таймер\n\t\tif (debounceTimers.current.has(key)) {\n\t\t\tclearTimeout(debounceTimers.current.get(key)!);\n\t\t}\n\n\t\t// Устанавливаем новый таймер\n\t\tconst timer = setTimeout(fn, delay);\n\t\tdebounceTimers.current.set(key, timer);\n\t}, []);\n\n\t/**\n\t * Очищает все дебаунс таймеры.\n\t */\n\tconst clearDebounceTimers = useCallback(() => {\n\t\tfor (const timer of debounceTimers.current.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tdebounceTimers.current.clear();\n\t}, []);\n\n\t// Очистка таймеров при размонтировании\n\tuseMemo(() => {\n\t\treturn () => {\n\t\t\tclearDebounceTimers();\n\t\t};\n\t}, [clearDebounceTimers]);\n\n\treturn {\n\t\t// Состояние данных\n\t\tdata: rawData,\n\t\tisLoading,\n\t\tisError,\n\n\t\tcodeKey,\n\t\ttextKey,\n\n\t\t// Функции для работы с коллекцией\n\t\tgetItems,\n\t\tfindSourceItemsByKeys,\n\t\tsetFilteredItems,\n\t\tgetPage,\n\t\tbuildSearchIndex,\n\t\tdebounce,\n\n\t\t// Вспомогательные данные\n\t\titemsMap,\n\t\tseparatedItems,\n\t\torderedKeys,\n\n\t\t// Управление запросом\n\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\trefetch,\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\tinvalidate: () => queryClient.invalidateQueries({ queryKey: createODataCollectionQueryKey(odata) }),\n\n\t\t// Метаданные для виртуализации\n\t\ttotalCount: rawData?.separated[codeKey]?.length || 0,\n\t\tpageSize\n\t};\n}\n","import { useEffect, useMemo, useState } from \"react\";\n\nimport { Query, useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Используется для получения последовательностей кодов.\n */\nexport function useODataCollectionChains(params: ODataServiceCollectionConfig[]) {\n\tconst queryClient = useQueryClient();\n\tconst [chains, setChains] = useState<ODataChainsMap>({});\n\n\tconst trackedKeys = useMemo(() => params.map((p) => createODataCollectionQueryKey(p)), [params]);\n\n\tuseEffect(() => {\n\t\tfunction updateChains() {\n\t\t\tconst newChains: ODataChainsMap = {};\n\n\t\t\tfor (const p of params) {\n\t\t\t\tconst key = createODataCollectionQueryKey(p);\n\t\t\t\tconst cached = queryClient.getQueryData<{ chain: { codeKey: string; count: number }[] }>(key);\n\t\t\t\tif (cached?.chain) {\n\t\t\t\t\tnewChains[`${p.service}.${p.target}`] = cached.chain;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetChains((prev) => {\n\t\t\t\t// не обновлять стейт, если данные не изменились (во избежание лишних рендеров)\n\t\t\t\tconst same =\n\t\t\t\t\tObject.keys(prev).length === Object.keys(newChains).length &&\n\t\t\t\t\tObject.entries(newChains).every(([k, v]) => prev[k] === v);\n\t\t\t\treturn same ? prev : newChains;\n\t\t\t});\n\t\t}\n\n\t\t// Первичная загрузка (на случай, если данные уже в кэше)\n\t\tupdateChains();\n\n\t\t// Подписка на изменения кэша\n\t\tconst unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n\t\t\t// Проверяем, затрагивает ли событие один из наших trackedKeys\n\t\t\tif (event?.query) {\n\t\t\t\tconst query = event.query as Query;\n\t\t\t\tconst isTracked = trackedKeys.some((key) => JSON.stringify(key) === JSON.stringify(query.queryKey));\n\t\t\t\tif (isTracked) {\n\t\t\t\t\tupdateChains();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn unsubscribe;\n\t}, [params, queryClient, trackedKeys]);\n\n\treturn chains;\n}\n","import { useState } from \"react\";\n\nimport { useODataCollectionStore } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { ODataCollectionModel } from \"./types\";\n\nexport function useODataCollectionModel(model: ODataCollectionModel): Required<ODataCollectionModel> {\n\t// NOTE: без подписки, потому что эти данные в рантайме не предполагается изменять в ближайшее время.\n\n\t// const defaultMaxVisibleItems = odataCollectionConfig.useMaxVisibleItems();\n\t// const defaultMinSearchCodeLength = odataCollectionConfig.useMinSearchCodeLength();\n\t// const defaultMinSearchTextLength = odataCollectionConfig.useMinSearchTextLength();\n\t// const defaultSearchDebounceDelay = odataCollectionConfig.useSearchDebounce();\n\n\tconst [stableModel] = useState(() => {\n\t\tconst defaultState = useODataCollectionStore.getState();\n\n\t\tconst {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems = defaultState.defaultMaxVisibleItems,\n\t\t\tminSearchCodeLength = defaultState.defaultMinSearchCodeLength,\n\t\t\tminSearchTextLength = defaultState.defaultMinSearchTextLength,\n\t\t\tsearchDebounceDelay = defaultState.defaultSearchDebounceDelay\n\t\t} = model;\n\t\treturn {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems,\n\t\t\tminSearchCodeLength,\n\t\t\tminSearchTextLength,\n\t\t\tsearchDebounceDelay\n\t\t};\n\t});\n\n\treturn stableModel;\n}\n","import { useMemo } from \"react\";\n\nimport {\n\ttype TableColumnDef,\n\ttype TableColumnFormattingMetaInput,\n\tcreateTableColumnVisibilityFromODataMetadata,\n\tcreateTableColumnsFromODataMetadata,\n\tenrichTableColumnsWithODataFormatting,\n\tresolveStableColumnId\n} from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { EntityColumnProperty, EntityMetadata, ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Собирает visibility-state только для тех leaf-колонок, которые сопоставились с metadata.\n */\nfunction collectMatchedColumnVisibility<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tvisibilityById: Readonly<Record<string, boolean>>\n): Record<string, boolean> {\n\tconst matchedVisibility: Record<string, boolean> = {};\n\n\tconst visitLeafColumns = (nestedColumns: readonly TableColumnDef<TData>[]) => {\n\t\tfor (const column of nestedColumns) {\n\t\t\tif (\"columns\" in column && Array.isArray(column.columns) && column.columns.length > 0) {\n\t\t\t\tvisitLeafColumns(column.columns as TableColumnDef<TData>[]);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst columnId = resolveStableColumnId(column);\n\t\t\tif (!columnId || !(columnId in visibilityById)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmatchedVisibility[columnId] = visibilityById[columnId];\n\t\t}\n\t};\n\n\tvisitLeafColumns(columns);\n\n\treturn matchedVisibility;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `build`.\n */\nexport interface UseODataTableColumnsBuildConfig extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим генерации колонок только по metadata.\n\t */\n\tmode: \"build\";\n\t/**\n\t * Позволяет определить видимость колонки при генерации.\n\t */\n\tresolveVisible?: (column: EntityColumnProperty) => boolean;\n\t/**\n\t * Позволяет переопределить заголовок колонки при генерации.\n\t */\n\tresolveHeader?: (column: EntityColumnProperty) => string;\n\t/**\n\t * Позволяет сразу навесить formatting-конфиг на generated column.\n\t */\n\tresolveFormatting?: (column: EntityColumnProperty) => TableColumnFormattingMetaInput | undefined;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `enrich`.\n */\nexport interface UseODataTableColumnsEnrichConfig<TData extends object> extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим обогащения уже существующих колонок.\n\t */\n\tmode: \"enrich\";\n\t/**\n\t * Существующий набор колонок для дозаполнения `meta.formatting.role/type`.\n\t */\n\tcolumns: readonly TableColumnDef<TData>[];\n}\n\n/**\n * Универсальный конфиг hook-адаптера колонок.\n */\nexport type UseODataTableColumnsConfig<TData extends object = Record<string, unknown>> =\n\tUseODataTableColumnsBuildConfig | UseODataTableColumnsEnrichConfig<TData>;\n\n/**\n * Результат работы hook-адаптера колонок.\n */\nexport interface UseODataTableColumnsResult<TData extends object> {\n\t/**\n\t * Итоговый набор колонок для `Table` или `TreeTable`.\n\t */\n\tcolumns: TableColumnDef<TData>[];\n\t/**\n\t * Стартовая карта видимости колонок для TanStack Table.\n\t */\n\tdefaultColumnVisibility: Record<string, boolean> | undefined;\n\t/**\n\t * Метаданные сущности, если они уже загружены.\n\t */\n\tmetadata: EntityMetadata | undefined;\n\t/**\n\t * Признак загрузки metadata.\n\t */\n\tisLoading: boolean;\n}\n\n/**\n * Возвращает колонки для `Table`/`TreeTable` на основе OData metadata.\n *\n * В режиме `build` генерирует базовый набор колонок из `metadata.columns`.\n * В режиме `enrich` дозаполняет уже существующие колонки typed-formatting контекстом.\n */\nexport function useODataTableColumns<TData extends object = Record<string, unknown>>(\n\tconfig: UseODataTableColumnsConfig<TData>\n): UseODataTableColumnsResult<TData> {\n\tconst { metadata, isLoading } = useODataMetadata(config);\n\n\tconst columns = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn config.mode === \"build\" ? [] : [...config.columns];\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnsFromODataMetadata<TData>(metadata.columns, {\n\t\t\t\tresolveHeader: config.resolveHeader,\n\t\t\t\tresolveFormatting: config.resolveFormatting\n\t\t\t});\n\t\t}\n\n\t\treturn enrichTableColumnsWithODataFormatting(config.columns, metadata.columns);\n\t}, [config, metadata]);\n\n\tconst defaultColumnVisibility = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnVisibilityFromODataMetadata(metadata.columns, {\n\t\t\t\tresolveVisible: config.resolveVisible\n\t\t\t});\n\t\t}\n\n\t\tconst visibilityById = createTableColumnVisibilityFromODataMetadata(metadata.columns);\n\n\t\treturn collectMatchedColumnVisibility(config.columns, visibilityById);\n\t}, [config, metadata]);\n\n\treturn {\n\t\tcolumns,\n\t\tdefaultColumnVisibility,\n\t\tmetadata,\n\t\tisLoading\n\t};\n}\n","import { notify } from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { QueryClient } from \"@tanstack/react-query\";\n\nimport { buildODataFetchRequest, ODataFetchRequestPreview } from \"./odataFetch\";\nimport {\n\tODataArrayOperationMethod,\n\tODataCreateFnOptions,\n\tODataDeleteFnOptions,\n\todataFetchFn,\n\tODataFetchFnImplementationArgs,\n\tODataFetchFnRequest,\n\tODataFetchFnRunner,\n\tODataFetchFnSharedOptions,\n\tODataFunctionImportFnOptions,\n\tODataQueryArrayTransform,\n\tODataQueryFnOptions,\n\tODataQuerySingleTransform,\n\tODataReadFnOptions,\n\tODataSingleFetchFnRequest,\n\tODataSingleOperationMethod,\n\tODataSingleTransform,\n\tODataUpdateFnOptions\n} from \"./odataFetchFn\";\nimport {\n\tbuildTargetPath,\n\tisFunctionImportMetadata,\n\tresolveODataTarget,\n\tresolveRequestBody,\n\tresolveRequestMethod,\n\tvalidateODataOperation\n} from \"./odataFetchFnHelpers\";\nimport { resolveODataBaseUrl } from \"./transport\";\nimport { getODataMetadataData } from \"./useODataMetadataQuery\";\n\nimport type {\n\tODataOperationMethod,\n\tODataServiceConfig,\n\tODataTargetMetadata,\n\tUnwrappedODataParameters,\n\tWrappedODataParameters\n} from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\ntype ODataDevHelperName =\n\t| \"odataFetchFnDev\"\n\t| \"odataCreateFnDev\"\n\t| \"odataUpdateFnDev\"\n\t| \"odataDeleteFnDev\"\n\t| \"odataReadFnDev\"\n\t| \"odataQueryFnDev\"\n\t| \"odataFunctionImportFnDev\";\n\ntype ODataFetchFnDevOptions<I> = ODataFetchFnSharedOptions<I> & {\n\tparams?: WrappedODataParameters;\n\tbody?: unknown;\n\ttransform?: unknown;\n};\n\ntype ODataDevRequestLogInfo = {\n\thelperName: ODataDevHelperName;\n\toperation: ODataOperationMethod;\n\todata: ODataServiceConfig;\n\ttarget: ODataTargetMetadata;\n\ttargetPath: string;\n\trequest: ODataFetchRequestPreview;\n\trequestMethod: string;\n\tparams: WrappedODataParameters;\n\tqueryOptions: unknown;\n\tbody: string | undefined;\n\tautoParse: boolean | undefined;\n\thasTransform: boolean;\n};\n\nfunction getConsole() {\n\treturn globalThis.console;\n}\n\nfunction headersToRecord(headers: HeadersInit | undefined) {\n\tconst result: Record<string, string> = {};\n\tnew Headers(headers).forEach((value, key) => {\n\t\tresult[key] = value;\n\t});\n\n\treturn result;\n}\n\nfunction parseRequestBodyForLog(body: BodyInit | null | undefined): unknown {\n\tif (body === undefined || body === null) return undefined;\n\tif (typeof body !== \"string\") return body;\n\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\treturn parsed;\n\t} catch {\n\t\treturn body;\n\t}\n}\n\nfunction isWriteRequest(method: string | undefined) {\n\treturn method !== undefined && ![\"GET\", \"HEAD\"].includes(method.toUpperCase());\n}\n\nfunction isSapRequestPreview(request: ODataFetchRequestPreview) {\n\tconst baseUrl = request.baseUrl ?? \"odata\";\n\tif (baseUrl !== \"\") return true;\n\n\treturn request.path.startsWith(\"/sap/\") || request.path.startsWith(\"/sap-dp0/\");\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string) {\n\tconst normalizedName = name.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedName);\n}\n\nfunction setDefaultHeader(headers: Record<string, string>, name: string, value: string) {\n\tif (hasHeader(headers, name)) return;\n\theaders[name] = value;\n}\n\nfunction buildTransportHeadersPreview(request: ODataFetchRequestPreview) {\n\tconst headers = headersToRecord(request.init.headers);\n\tconst method = request.init.method;\n\tconst sapRequest = isSapRequestPreview(request);\n\n\tsetDefaultHeader(headers, \"DataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"MaxDataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"Accept\", \"application/json\");\n\n\theaders[\"sap-language\"] = \"ru\";\n\n\tif (sapRequest) {\n\t\theaders[\"sap-contextid-accept\"] = \"header\";\n\t}\n\n\tif (isWriteRequest(method) && request.init.body) {\n\t\tsetDefaultHeader(headers, \"Content-Type\", \"application/json\");\n\t}\n\n\tif (isWriteRequest(method) && sapRequest) {\n\t\tsetDefaultHeader(headers, \"x-csrf-token\", \"<получается отдельным GET перед реальным write-запросом>\");\n\t}\n\n\treturn headers;\n}\n\nfunction getTargetKind(target: ODataTargetMetadata) {\n\tif (isFunctionImportMetadata(target)) return \"FunctionImport\";\n\treturn target.result ? \"Parameterized Entity\" : \"Entity\";\n}\n\nfunction logObjectSection(title: string, value: unknown) {\n\tconst logger = getConsole();\n\tlogger.groupCollapsed(title);\n\tlogger.info(value);\n\tlogger.groupEnd();\n}\n\nfunction logODataDevRequest(info: ODataDevRequestLogInfo) {\n\tconst logger = getConsole();\n\tconst bodyPreview = parseRequestBodyForLog(info.request.init.body);\n\tconst initHeaders = headersToRecord(info.request.init.headers);\n\tconst transportHeaders = buildTransportHeadersPreview(info.request);\n\tconst requestInitPreview = {\n\t\tmethod: info.request.init.method,\n\t\theaders: initHeaders,\n\t\tbody: bodyPreview,\n\t\thasSignal: Boolean(info.request.init.signal)\n\t};\n\n\tlogger.groupCollapsed(`[OData DEV] ${info.requestMethod} ${info.request.fullUrl}`);\n\tlogger.table([\n\t\t{\n\t\t\thelper: info.helperName,\n\t\t\toperation: info.operation,\n\t\t\ttarget: info.odata.target,\n\t\t\ttargetKind: getTargetKind(info.target),\n\t\t\tservice: info.odata.service,\n\t\t\trealFetch: \"не выполнялся\"\n\t\t}\n\t]);\n\tlogger.info(\"Итоговый URL:\", info.request.fullUrl);\n\tlogger.info(\"Path без base URL:\", info.request.path);\n\tlogger.info(\"Target path до query options:\", info.targetPath);\n\tlogger.info(\"Query string:\", info.request.queryString || \"<пусто>\");\n\tlogger.info(\"Body:\", bodyPreview ?? \"<пусто>\");\n\tlogger.info(\"Auto parse:\", info.autoParse ?? false);\n\tlogger.info(\"Transform:\", info.hasTransform ? \"передан, но не вызывается без ответа backend\" : \"не передан\");\n\tlogger.info(\"Dry-run result:\", info.operation === \"query\" ? { data: [], totalCount: 0 } : { data: undefined });\n\tlogObjectSection(\"OData config\", info.odata);\n\tlogObjectSection(\"Target metadata\", info.target);\n\tlogObjectSection(\"Target params\", info.params);\n\tlogObjectSection(\"Query options\", info.queryOptions);\n\tlogObjectSection(\"RequestInit, переданный в transport\", requestInitPreview);\n\tlogObjectSection(\"Заголовки после transport defaults (без реального fetch)\", transportHeaders);\n\tlogger.groupEnd();\n}\n\nfunction notifyODataDevHelperCall(helperName: ODataDevHelperName) {\n\tnotify.warning(`${helperName}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, {\n\t\ttitle: \"OData DEV helper\"\n\t});\n}\n\nfunction createODataFetchFnDevRunner<I>(\n\tmethod: ODataOperationMethod,\n\topts: ODataFetchFnDevOptions<I>,\n\thelperName: ODataDevHelperName\n): ODataFetchFnRunner<unknown> {\n\tconst { odata, options = {}, init = {}, autoParse, swCache } = opts;\n\tconst params = opts.params ?? {};\n\n\treturn async ({ client, signal }: { client: QueryClient; signal?: AbortSignal }) => {\n\t\tnotifyODataDevHelperCall(helperName);\n\n\t\tconst baseUrl = resolveODataBaseUrl(odata.service, options.baseUrl);\n\t\tconst serviceMetadata = await getODataMetadataData({ service: odata.service, baseUrl }, client);\n\t\tif (!serviceMetadata) {\n\t\t\tthrow new Error(`Не удалось загрузить metadata OData-сервиса '${odata.service}'`);\n\t\t}\n\n\t\tconst target = resolveODataTarget(serviceMetadata, odata.target);\n\n\t\tvalidateODataOperation(target, method, odata);\n\n\t\tconst body = resolveRequestBody(opts.body, method);\n\t\tconst requestMethod = resolveRequestMethod(target, method);\n\t\tconst targetPath = buildTargetPath(target, odata, params, method);\n\n\t\tconst queryOptions = swCache ? { ...options, baseUrl, swCache } : { ...options, baseUrl };\n\t\tconst requestInit = { ...init, method: requestMethod, body, signal };\n\t\tconst request = buildODataFetchRequest(targetPath, queryOptions, requestInit);\n\n\t\tlogODataDevRequest({\n\t\t\thelperName,\n\t\t\toperation: method,\n\t\t\todata,\n\t\t\ttarget,\n\t\t\ttargetPath,\n\t\t\trequest,\n\t\t\trequestMethod,\n\t\t\tparams,\n\t\t\tqueryOptions,\n\t\t\tbody,\n\t\t\tautoParse,\n\t\t\thasTransform: Boolean(opts.transform)\n\t\t});\n\n\t\tif (method === \"query\") {\n\t\t\treturn { data: [], totalCount: 0 };\n\t\t}\n\n\t\treturn { data: undefined };\n\t};\n}\n\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }): ODataFetchFnRunner<O[]>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, I, P> & { transform?: undefined }): ODataFetchFnRunner<I[]>;\nexport function odataFetchFnDev<\n\tI,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataSingleOperationMethod = ODataSingleOperationMethod\n>(method: M, opts: ODataSingleFetchFnRequest<M, I, I, T, P> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataFetchFnDev<I, O = I, T = I, M extends ODataSingleOperationMethod = ODataSingleOperationMethod>(\n\tmethod: M,\n\topts: ODataSingleFetchFnRequest<M, I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataOperationMethod = ODataOperationMethod\n>(method: M, opts: ODataFetchFnRequest<M, I, O, T, P>): ODataFetchFnRunner<unknown>;\nexport function odataFetchFnDev(...args: ODataFetchFnImplementationArgs): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\tswitch (args[0]) {\n\t\t\tcase \"create\": {\n\t\t\t\treturn odataFetchFn(\"create\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\treturn odataFetchFn(\"update\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"delete\": {\n\t\t\t\treturn odataFetchFn(\"delete\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"read\": {\n\t\t\t\treturn odataFetchFn(\"read\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"query\": {\n\t\t\t\treturn odataFetchFn(\"query\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"fi\": {\n\t\t\t\treturn odataFetchFn(\"fi\", args[1]);\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst checker: never = args[0];\n\t\t\t\tvoid checker;\n\n\t\t\t\tthrow new Error(\"Неподдерживаемая OData operation в odataFetchFnDev\");\n\t\t\t}\n\t\t}\n\t}\n\n\tconst [method, opts] = args;\n\treturn createODataFetchFnDevRunner(method, opts, \"odataFetchFnDev\");\n}\n\nexport function odataCreateFnDev<I, T = I>(opts: ODataCreateFnOptions<I, I, T> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataCreateFnDev<I, O = I, T = I>(\n\topts: ODataCreateFnOptions<I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataCreateFnDev<I, O = I, T = I>(opts: ODataCreateFnOptions<I, O, T>): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, never, \"create\">(\"create\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"create\", opts, \"odataCreateFnDev\");\n}\n\nexport function odataUpdateFnDev<I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, I, T, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, P, \"update\">(\"update\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"update\", opts, \"odataUpdateFnDev\");\n}\n\nexport function odataDeleteFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"delete\">(\"delete\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"delete\", opts, \"odataDeleteFnDev\");\n}\n\nexport function odataReadFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"read\">(\"read\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"read\", opts, \"odataReadFnDev\");\n}\n\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }\n): ODataFetchFnRunner<O[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform?: undefined }\n): ODataFetchFnRunner<I[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, void, P, \"query\">(\"query\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"query\", opts, \"odataQueryFnDev\");\n}\n\nexport function odataFunctionImportFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"fi\">(\"fi\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"fi\", opts, \"odataFunctionImportFnDev\");\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ODataCollectionResult } from "./useODataCollectionQuery";
2
+ import type { CollectionItem } from "@ryuzaki13/react-foundation-lib/odata";
3
+ /**
4
+ * Создаёт observer-проекцию канонического справочника с сортировкой по text.
5
+ *
6
+ * Query cache и persistence продолжают хранить один code-sorted snapshot.
7
+ * Проекция копирует только массивы ссылок в `separated`: исходные строки,
8
+ * объекты элементов, `items`, `chain` и metadata остаются общими.
9
+ */
10
+ export declare function projectODataCollectionSortByText<T extends CollectionItem>(source: ODataCollectionResult<T>): ODataCollectionResult<T>;
11
+ //# sourceMappingURL=projectODataCollectionSort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectODataCollectionSort.d.ts","sourceRoot":"","sources":["../../src/odata/projectODataCollectionSort.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,cAAc,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAsBrI"}
@@ -21,7 +21,12 @@ export interface ODataCollectionConfig extends ODataServiceCollectionConfig {
21
21
  */
22
22
  excludeEmpty?: true;
23
23
  /**
24
- * Сортировка коллекции по code (`true`) или по text (`false`).
24
+ * Сортировка consumer-представления по code (`true`) или по text (`false`).
25
+ *
26
+ * Параметр не разделяет общий Query snapshot: TanStack Query создаёт
27
+ * observer-проекцию, и разные контролы одного справочника могут выбирать
28
+ * свой порядок без повторной загрузки коллекции.
29
+ *
25
30
  * По умолчанию `true`
26
31
  */
27
32
  sortByCode?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/odata/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/odata/types.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,13 @@ export interface ODataCollectionResult<T extends CollectionItem> {
6
6
  items: T[];
7
7
  keyPairs: CollectionPair[];
8
8
  keyPairsMap: Record<string, string>;
9
+ /**
10
+ * Массивы элементов по уровням справочника.
11
+ *
12
+ * Query cache хранит канонический порядок по code, а конкретный observer
13
+ * может получить проекцию по text. Один snapshot при этом переиспользуется
14
+ * ракурсами с разными `sortByCode`.
15
+ */
9
16
  separated: Record<string, T[]>;
10
17
  chain: {
11
18
  codeKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"useODataCollectionQuery.d.ts","sourceRoot":"","sources":["../../src/odata/useODataCollectionQuery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvH,OAAO,EAA4B,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAIjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAGN,yBAAyB,EAEzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,cAAc;IAC9D,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,kCAAkC;IAC3C,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,UAQvF;AAMD;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,SAAS,cAAc,EACzE,OAAO,EAAE,kCAAkC,EAC3C,UAAU,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,SAAS,WA0BhD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAkGxI"}
1
+ {"version":3,"file":"useODataCollectionQuery.d.ts","sourceRoot":"","sources":["../../src/odata/useODataCollectionQuery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvH,OAAO,EAA4B,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAKjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAGN,yBAAyB,EAEzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,cAAc;IAC9D,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,kCAAkC;IAC3C,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,UAQvF;AAMD;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,SAAS,cAAc,EACzE,OAAO,EAAE,kCAAkC,EAC3C,UAAU,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,SAAS,WA0BhD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CA8GxI"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuzaki13/react-foundation-api",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "description": "Reusable React and TypeScript foundation API helpers and transport adapters.",
5
5
  "license": "MIT",
6
6
  "author": "Ryuzaki13",
@@ -1,3 +0,0 @@
1
- import type { CollectionItem } from "@ryuzaki13/react-foundation-lib/odata";
2
- export declare function useTextServiceQuery<T extends CollectionItem>(target: string): import("@tanstack/react-query").UseQueryResult<import("./useODataCollectionQuery").ODataCollectionResult<T>>;
3
- //# sourceMappingURL=useTextServiceQuery.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useTextServiceQuery.d.ts","sourceRoot":"","sources":["../../src/odata/useTextServiceQuery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,cAAc,EAAE,MAAM,EAAE,MAAM,gHAE3E"}