@ryuzaki13/react-foundation-api 1.1.11 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/odata/createODataCollectionQueryKey.d.ts +1 -0
- package/dist/odata/createODataCollectionQueryKey.d.ts.map +1 -1
- package/dist/odata/index.js +159 -140
- package/dist/odata/index.js.map +1 -1
- package/dist/odata/projectODataCollectionSort.d.ts +11 -0
- package/dist/odata/projectODataCollectionSort.d.ts.map +1 -0
- package/dist/odata/types.d.ts +6 -1
- package/dist/odata/types.d.ts.map +1 -1
- package/dist/odata/useODataCollectionQuery.d.ts +7 -0
- package/dist/odata/useODataCollectionQuery.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -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;
|
|
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"}
|
package/dist/odata/index.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
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
|
|
3
|
-
import { logError as
|
|
4
|
-
import { parseDate as
|
|
5
|
-
import { compareStrings as
|
|
6
|
-
import { useCallback as
|
|
7
|
-
import { queryOptions as
|
|
8
|
-
import { buildSeparatedArrays as
|
|
9
|
-
import { persistedQueryMeta as
|
|
10
|
-
import { buildEntityPath as
|
|
11
|
-
import { createTableColumnVisibilityFromODataMetadata as
|
|
12
|
-
import { notify as
|
|
2
|
+
import { S as w, _ as ee, a as te, b as ne, c as re, d as ie, f as ae, g as T, h as oe, i as se, l as ce, m as le, n as ue, o as de, p as fe, r as E, s as pe, t as me, u as he, v as ge, 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 be } from "@ryuzaki13/react-foundation-lib/string-comparison";
|
|
6
|
+
import { useCallback as O, useEffect as k, useMemo as A, useRef as xe, useState as j } from "react";
|
|
7
|
+
import { queryOptions as Se, useQuery as M, useQueryClient as N } from "@tanstack/react-query";
|
|
8
|
+
import { buildSeparatedArrays as Ce, useODataCollectionStore as we } from "@ryuzaki13/react-foundation-lib/odata";
|
|
9
|
+
import { persistedQueryMeta as P } from "@ryuzaki13/react-foundation-lib/query-client";
|
|
10
|
+
import { buildEntityPath as Te } from "@ryuzaki13/react-foundation-lib/odata-service";
|
|
11
|
+
import { createTableColumnVisibilityFromODataMetadata as Ee, createTableColumnsFromODataMetadata as De, enrichTableColumnsWithODataFormatting as Oe, resolveStableColumnId as ke } from "@ryuzaki13/react-foundation-lib/table";
|
|
12
|
+
import { notify as Ae } from "@ryuzaki13/react-foundation-lib/notifications";
|
|
13
13
|
//#region src/odata/createODataCollectionQueryKey.ts
|
|
14
|
-
var Me = () => [...
|
|
14
|
+
var je = 2, Me = () => [...w, "collection"], F = ({ service: e, target: t, limitedKeys: n, serverFilter: r }) => [...Me(), {
|
|
15
|
+
version: je,
|
|
15
16
|
service: e,
|
|
16
17
|
target: t,
|
|
17
18
|
limitedKeys: n,
|
|
@@ -88,7 +89,7 @@ function Ie(e, t, n) {
|
|
|
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 ?
|
|
92
|
+
return n !== void 0 && i !== void 0 ? n - i : n === void 0 ? i === void 0 ? be(e, t) : 1 : -1;
|
|
92
93
|
});
|
|
93
94
|
return {
|
|
94
95
|
...e,
|
|
@@ -101,58 +102,75 @@ function Ie(e, t, n) {
|
|
|
101
102
|
async function Le(e) {
|
|
102
103
|
let { url: t, query: n, signal: r } = e;
|
|
103
104
|
try {
|
|
104
|
-
let e = await
|
|
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
|
|
109
|
+
return ve("Ошибка загрузки справочника:", e), { items: [] };
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
//#endregion
|
|
113
|
+
//#region src/odata/projectODataCollectionSort.ts
|
|
114
|
+
var I = /* @__PURE__ */ new WeakMap();
|
|
115
|
+
function Re(e) {
|
|
116
|
+
let t = I.get(e);
|
|
117
|
+
if (t) return t;
|
|
118
|
+
let n = !1, r = Object.fromEntries(Object.entries(e.separated).map(([t, r]) => {
|
|
119
|
+
let i = e.keyPairsMap[t];
|
|
120
|
+
return !i || r.length < 2 ? [t, r] : (n = !0, [t, [...r].sort((e, t) => be(String(e[i] ?? ""), String(t[i] ?? "")))]);
|
|
121
|
+
}));
|
|
122
|
+
if (!n) return e;
|
|
123
|
+
let i = {
|
|
124
|
+
...e,
|
|
125
|
+
separated: r
|
|
126
|
+
};
|
|
127
|
+
return I.set(e, i), i;
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
112
130
|
//#region src/odata/useODataCollectionUpdatesQuery.ts
|
|
113
|
-
var
|
|
114
|
-
...
|
|
131
|
+
var ze = __APP_BUILD_ID__, Be = 1e3 * 60 * 60 * 4, L = 1e3 * 60 * 60 * 24 * 7, R = "ttl=forever;name=ref", z = "bust=forever;name=ref", B = "ttl=4h;name=ref-updates", V = () => [
|
|
132
|
+
...w,
|
|
115
133
|
"collection-updates",
|
|
116
|
-
{ buildId:
|
|
134
|
+
{ buildId: ze }
|
|
117
135
|
];
|
|
118
|
-
function
|
|
136
|
+
function Ve(e) {
|
|
119
137
|
return {
|
|
120
138
|
...e,
|
|
121
|
-
lastChangedAt:
|
|
139
|
+
lastChangedAt: ye(e.lastChanged)
|
|
122
140
|
};
|
|
123
141
|
}
|
|
124
|
-
function
|
|
125
|
-
let n = e.map(
|
|
142
|
+
function H(e, t) {
|
|
143
|
+
let n = e.map(Ve);
|
|
126
144
|
return {
|
|
127
145
|
items: n,
|
|
128
146
|
byEntityName: n.reduce((e, t) => (t.entityName && (e[t.entityName] = t), e), {}),
|
|
129
147
|
fetchedAt: t,
|
|
130
|
-
coverageStartedAt: t -
|
|
148
|
+
coverageStartedAt: t - L
|
|
131
149
|
};
|
|
132
150
|
}
|
|
133
|
-
function
|
|
151
|
+
function U() {
|
|
134
152
|
return async ({ signal: t }) => {
|
|
135
153
|
let n = Date.now(), r = S().collectionUpdates;
|
|
136
|
-
return r ?
|
|
154
|
+
return r ? H((await D(`/${r.service}/${r.target}`, {
|
|
137
155
|
baseUrl: e(r.service, r.baseUrl),
|
|
138
|
-
swCache:
|
|
139
|
-
}, { signal: t })).data, Math.max(n, Date.now())) :
|
|
156
|
+
swCache: B
|
|
157
|
+
}, { signal: t })).data, Math.max(n, Date.now())) : H([], n);
|
|
140
158
|
};
|
|
141
159
|
}
|
|
142
|
-
var
|
|
143
|
-
queryKey:
|
|
144
|
-
queryFn:
|
|
145
|
-
meta:
|
|
146
|
-
staleTime: e.staleTime ??
|
|
160
|
+
var W = (e = {}) => Se({
|
|
161
|
+
queryKey: V(),
|
|
162
|
+
queryFn: U(),
|
|
163
|
+
meta: P,
|
|
164
|
+
staleTime: e.staleTime ?? Be,
|
|
147
165
|
gcTime: Infinity
|
|
148
166
|
});
|
|
149
|
-
function
|
|
150
|
-
return
|
|
167
|
+
function G(e = {}) {
|
|
168
|
+
return M(W(e));
|
|
151
169
|
}
|
|
152
170
|
//#endregion
|
|
153
171
|
//#region src/odata/useODataMetadata.ts
|
|
154
|
-
function
|
|
155
|
-
let { data: t, dataUpdatedAt: n = 0, isLoading: r, isLoadingError: i } =
|
|
172
|
+
function K(e) {
|
|
173
|
+
let { data: t, dataUpdatedAt: n = 0, isLoading: r, isLoadingError: i } = ge({ service: e.service }), a = t?.entities[e.target];
|
|
156
174
|
if (!r && !a && t?.functionImports[e.target]) throw Error(`OData target '${e.target}' является FunctionImport и не может использоваться как сущность`);
|
|
157
175
|
if (i) throw Error(`Ошибка загрузки метаданных сервиса ${e.service}`);
|
|
158
176
|
return {
|
|
@@ -163,32 +181,32 @@ function W(e) {
|
|
|
163
181
|
}
|
|
164
182
|
//#endregion
|
|
165
183
|
//#region src/odata/useODataEntity.ts
|
|
166
|
-
var
|
|
167
|
-
function
|
|
168
|
-
let { metadata: t, metadataUpdatedAt: n, isLoading: r } =
|
|
184
|
+
var q = "Использование actions недопустимо до окончания загрузки metadata";
|
|
185
|
+
function J(e) {
|
|
186
|
+
let { metadata: t, metadataUpdatedAt: n, isLoading: r } = K(e);
|
|
169
187
|
return {
|
|
170
188
|
config: e,
|
|
171
189
|
metadata: t,
|
|
172
190
|
metadataUpdatedAt: n,
|
|
173
191
|
isLoading: r,
|
|
174
|
-
actions:
|
|
192
|
+
actions: A(() => ({
|
|
175
193
|
getEntityPath: (n = {}) => {
|
|
176
|
-
if (!t) throw Error(
|
|
177
|
-
return
|
|
194
|
+
if (!t) throw Error(q);
|
|
195
|
+
return Te(t, e, n);
|
|
178
196
|
},
|
|
179
197
|
getKeys: () => {
|
|
180
|
-
if (!t) throw Error(
|
|
198
|
+
if (!t) throw Error(q);
|
|
181
199
|
return t.columns?.map((e) => e.id);
|
|
182
200
|
},
|
|
183
201
|
getKeyPairs: () => {
|
|
184
|
-
if (!t) throw Error(
|
|
202
|
+
if (!t) throw Error(q);
|
|
185
203
|
return t.columns?.filter((e) => e.semanticType === "code" && e.linkedColumnId).map((e) => ({
|
|
186
204
|
codeKey: e.id,
|
|
187
205
|
textKey: e.linkedColumnId
|
|
188
206
|
}));
|
|
189
207
|
},
|
|
190
208
|
getKeyPairsMap: () => {
|
|
191
|
-
if (!t) throw Error(
|
|
209
|
+
if (!t) throw Error(q);
|
|
192
210
|
let e = {};
|
|
193
211
|
for (let n of t.columns ?? []) n.semanticType === "code" && n.linkedColumnId && (e[n.id] = n.linkedColumnId);
|
|
194
212
|
return e;
|
|
@@ -198,20 +216,20 @@ function K(e) {
|
|
|
198
216
|
}
|
|
199
217
|
//#endregion
|
|
200
218
|
//#region src/odata/useODataCollectionQuery.ts
|
|
201
|
-
function
|
|
219
|
+
function Y(e, t) {
|
|
202
220
|
if (!t) return e;
|
|
203
221
|
let n = e.trim().toLowerCase();
|
|
204
|
-
return n === "off" || n.startsWith("bust=") ? e : n.startsWith("ttl=") ? e.replace(/^\s*ttl=/i, "bust=") :
|
|
222
|
+
return n === "off" || n.startsWith("bust=") ? e : n.startsWith("ttl=") ? e.replace(/^\s*ttl=/i, "bust=") : z;
|
|
205
223
|
}
|
|
206
|
-
function
|
|
224
|
+
function X(e) {
|
|
207
225
|
return typeof e == "number" && Number.isFinite(e) && e > 0;
|
|
208
226
|
}
|
|
209
|
-
function
|
|
227
|
+
function He(e, t) {
|
|
210
228
|
let n = t?.cacheUpdatedAt ?? 0, r = e.update?.lastChangedAt?.getTime();
|
|
211
|
-
return !!(
|
|
229
|
+
return !!(X(r) && (!t || !n || r > n) || X(e.metadataUpdatedAt) && (!t || !n || e.metadataUpdatedAt > n) || X(e.updatesCoverageStartedAt) && (!t || !n || n < e.updatesCoverageStartedAt));
|
|
212
230
|
}
|
|
213
|
-
function
|
|
214
|
-
let { service: t, target: n, limitedKeys: r, excludeEmpty: i, sortByCode: a, serverFilter: o, clientFilter: s, swCache: c =
|
|
231
|
+
function Ue(e) {
|
|
232
|
+
let { service: t, target: n, limitedKeys: r, excludeEmpty: i, sortByCode: a, serverFilter: o, clientFilter: s, swCache: c = R } = e, l = N(), { actions: u, metadata: d, metadataUpdatedAt: f, isLoading: p } = J(e), m = G(), h = A(() => F({
|
|
215
233
|
service: t,
|
|
216
234
|
target: n,
|
|
217
235
|
limitedKeys: r,
|
|
@@ -221,60 +239,61 @@ function X(e) {
|
|
|
221
239
|
n,
|
|
222
240
|
r,
|
|
223
241
|
o
|
|
224
|
-
]), g = l.getQueryData(h), _ = m.data?.byEntityName[n], v =
|
|
242
|
+
]), g = l.getQueryData(h), _ = m.data?.byEntityName[n], v = He({
|
|
225
243
|
update: _,
|
|
226
244
|
metadataUpdatedAt: f,
|
|
227
245
|
updatesCoverageStartedAt: m.data?.coverageStartedAt
|
|
228
|
-
}, g), y =
|
|
229
|
-
return
|
|
246
|
+
}, g), y = Y(c, v), b = m.isError || m.isSuccess && !m.isFetching;
|
|
247
|
+
return k(() => {
|
|
230
248
|
!g || !v || l.invalidateQueries({ queryKey: h });
|
|
231
249
|
}, [
|
|
232
250
|
g,
|
|
233
251
|
l,
|
|
234
252
|
h,
|
|
235
253
|
v
|
|
236
|
-
]),
|
|
254
|
+
]), M({
|
|
237
255
|
queryKey: h,
|
|
238
256
|
queryFn: async ({ signal: e }) => {
|
|
239
|
-
let
|
|
257
|
+
let a = Date.now(), c = r ? [...r] : u.getKeys(), l = u.getKeyPairs(), d = u.getKeyPairsMap();
|
|
240
258
|
if (r) for (let e of r) {
|
|
241
|
-
let t =
|
|
242
|
-
t && !
|
|
259
|
+
let t = d[e];
|
|
260
|
+
t && !c.includes(t) && c.push(t);
|
|
243
261
|
}
|
|
244
|
-
let { items:
|
|
262
|
+
let { items: p } = await Le({
|
|
245
263
|
url: `/${t}/${n}`,
|
|
246
264
|
query: {
|
|
247
|
-
select:
|
|
265
|
+
select: c,
|
|
248
266
|
expression: o,
|
|
249
267
|
swCache: y
|
|
250
268
|
},
|
|
251
269
|
signal: e
|
|
252
|
-
}),
|
|
253
|
-
s && (
|
|
254
|
-
let
|
|
270
|
+
}), m = p;
|
|
271
|
+
s && (m = p.filter(s));
|
|
272
|
+
let h = Ce(m, l, i, !0), g = l.map((e) => ({
|
|
255
273
|
codeKey: e.codeKey,
|
|
256
|
-
count:
|
|
274
|
+
count: h[e.codeKey].length
|
|
257
275
|
})).sort((e, t) => e.count - t.count);
|
|
258
276
|
return {
|
|
259
|
-
items:
|
|
260
|
-
keyPairs:
|
|
261
|
-
keyPairsMap:
|
|
262
|
-
separated:
|
|
263
|
-
chain:
|
|
264
|
-
count:
|
|
265
|
-
cacheUpdatedAt: Math.max(
|
|
277
|
+
items: m,
|
|
278
|
+
keyPairs: l,
|
|
279
|
+
keyPairsMap: d,
|
|
280
|
+
separated: h,
|
|
281
|
+
chain: g,
|
|
282
|
+
count: m.length,
|
|
283
|
+
cacheUpdatedAt: Math.max(a, Date.now(), _?.lastChangedAt?.getTime() ?? 0, f)
|
|
266
284
|
};
|
|
267
285
|
},
|
|
268
286
|
enabled: !!(!p && d && t && n && b),
|
|
269
|
-
meta:
|
|
287
|
+
meta: P,
|
|
270
288
|
staleTime: 1e3 * 60 * 60 * 2,
|
|
271
|
-
gcTime: 1e3 * 60 * 60 * 1
|
|
289
|
+
gcTime: 1e3 * 60 * 60 * 1,
|
|
290
|
+
select: a === !1 ? Re : void 0
|
|
272
291
|
});
|
|
273
292
|
}
|
|
274
293
|
//#endregion
|
|
275
294
|
//#region src/odata/useODataCollection.ts
|
|
276
|
-
function
|
|
277
|
-
let { codeKey: r, maxVisibleItems: i } = t, { data: a, isLoading: o, isError: s, refetch: c } =
|
|
295
|
+
function We({ odata: e, model: t, pageSize: n = 50 }) {
|
|
296
|
+
let { codeKey: r, maxVisibleItems: i } = t, { data: a, isLoading: o, isError: s, refetch: c } = Ue(e), l = a?.keyPairsMap[r] ?? "", u = N(), [d, f] = j(), p = xe(/* @__PURE__ */ new Map()), { itemsMap: m, separatedItems: h, orderedKeys: g } = A(() => {
|
|
278
297
|
let e = /* @__PURE__ */ new Map(), t = [], n = [];
|
|
279
298
|
if (a && a.separated[r]) {
|
|
280
299
|
n = a.separated[r];
|
|
@@ -288,7 +307,7 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
288
307
|
separatedItems: n,
|
|
289
308
|
orderedKeys: t
|
|
290
309
|
};
|
|
291
|
-
}, [a, r]), _ =
|
|
310
|
+
}, [a, r]), _ = O((e) => {
|
|
292
311
|
let t = a?.separated[r];
|
|
293
312
|
if (!t) return /* @__PURE__ */ new Map();
|
|
294
313
|
let n = /* @__PURE__ */ new Map();
|
|
@@ -300,11 +319,11 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
300
319
|
}
|
|
301
320
|
}
|
|
302
321
|
return n;
|
|
303
|
-
}, [a, r]), v =
|
|
322
|
+
}, [a, r]), v = O((e) => {
|
|
304
323
|
f(() => {
|
|
305
324
|
if (e?.length) return new Set(e.map((e) => e[r]));
|
|
306
325
|
});
|
|
307
|
-
}, [r]), y =
|
|
326
|
+
}, [r]), y = O((e, t) => {
|
|
308
327
|
if (!g.length) return [];
|
|
309
328
|
let n = i, a = /* @__PURE__ */ new Set(), o = [];
|
|
310
329
|
if (t?.length) for (let e = 0; e < t.length; e++) a.add(t[e][r]);
|
|
@@ -324,26 +343,26 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
324
343
|
m,
|
|
325
344
|
d,
|
|
326
345
|
l
|
|
327
|
-
]), b =
|
|
346
|
+
]), b = O((e) => {
|
|
328
347
|
let t = a?.separated[r] || [], i = e * n, o = i + n;
|
|
329
348
|
return t.slice(i, o);
|
|
330
349
|
}, [
|
|
331
350
|
a,
|
|
332
351
|
n,
|
|
333
352
|
r
|
|
334
|
-
]), x =
|
|
353
|
+
]), x = O((e, t) => {
|
|
335
354
|
if (!a) return [];
|
|
336
355
|
let n = new Set(t);
|
|
337
356
|
return a.items.filter((t) => n.has(t[e]));
|
|
338
|
-
}, [a]), S =
|
|
357
|
+
}, [a]), S = O((e, t, n = 200) => {
|
|
339
358
|
p.current.has(e) && clearTimeout(p.current.get(e));
|
|
340
359
|
let r = setTimeout(t, n);
|
|
341
360
|
p.current.set(e, r);
|
|
342
|
-
}, []), C =
|
|
361
|
+
}, []), C = O(() => {
|
|
343
362
|
for (let e of p.current.values()) clearTimeout(e);
|
|
344
363
|
p.current.clear();
|
|
345
364
|
}, []);
|
|
346
|
-
return
|
|
365
|
+
return A(() => () => {
|
|
347
366
|
C();
|
|
348
367
|
}, [C]), {
|
|
349
368
|
data: a,
|
|
@@ -361,20 +380,20 @@ function Ve({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
361
380
|
separatedItems: h,
|
|
362
381
|
orderedKeys: g,
|
|
363
382
|
refetch: c,
|
|
364
|
-
invalidate: () => u.invalidateQueries({ queryKey:
|
|
383
|
+
invalidate: () => u.invalidateQueries({ queryKey: F(e) }),
|
|
365
384
|
totalCount: a?.separated[r]?.length || 0,
|
|
366
385
|
pageSize: n
|
|
367
386
|
};
|
|
368
387
|
}
|
|
369
388
|
//#endregion
|
|
370
389
|
//#region src/odata/useODataCollectionChains.ts
|
|
371
|
-
function
|
|
372
|
-
let t =
|
|
373
|
-
return
|
|
390
|
+
function Ge(e) {
|
|
391
|
+
let t = N(), [n, r] = j({}), i = A(() => e.map((e) => F(e)), [e]);
|
|
392
|
+
return k(() => {
|
|
374
393
|
function n() {
|
|
375
394
|
let n = {};
|
|
376
395
|
for (let r of e) {
|
|
377
|
-
let e =
|
|
396
|
+
let e = F(r), i = t.getQueryData(e);
|
|
378
397
|
i?.chain && (n[`${r.service}.${r.target}`] = i.chain);
|
|
379
398
|
}
|
|
380
399
|
r((e) => Object.keys(e).length === Object.keys(n).length && Object.entries(n).every(([t, n]) => e[t] === n) ? e : n);
|
|
@@ -393,9 +412,9 @@ function He(e) {
|
|
|
393
412
|
}
|
|
394
413
|
//#endregion
|
|
395
414
|
//#region src/odata/useODataCollectionModel.ts
|
|
396
|
-
function
|
|
397
|
-
let [t] =
|
|
398
|
-
let t =
|
|
415
|
+
function Ke(e) {
|
|
416
|
+
let [t] = j(() => {
|
|
417
|
+
let t = we.getState(), { codeKey: n, maxVisibleItems: r = t.defaultMaxVisibleItems, minSearchCodeLength: i = t.defaultMinSearchCodeLength, minSearchTextLength: a = t.defaultMinSearchTextLength, searchDebounceDelay: o = t.defaultSearchDebounceDelay } = e;
|
|
399
418
|
return {
|
|
400
419
|
codeKey: n,
|
|
401
420
|
maxVisibleItems: r,
|
|
@@ -408,31 +427,31 @@ function Ue(e) {
|
|
|
408
427
|
}
|
|
409
428
|
//#endregion
|
|
410
429
|
//#region src/odata/useODataTableColumns.ts
|
|
411
|
-
function
|
|
430
|
+
function qe(e, t) {
|
|
412
431
|
let n = {}, r = (e) => {
|
|
413
432
|
for (let i of e) {
|
|
414
433
|
if ("columns" in i && Array.isArray(i.columns) && i.columns.length > 0) {
|
|
415
434
|
r(i.columns);
|
|
416
435
|
continue;
|
|
417
436
|
}
|
|
418
|
-
let e =
|
|
437
|
+
let e = ke(i);
|
|
419
438
|
!e || !(e in t) || (n[e] = t[e]);
|
|
420
439
|
}
|
|
421
440
|
};
|
|
422
441
|
return r(e), n;
|
|
423
442
|
}
|
|
424
|
-
function
|
|
425
|
-
let { metadata: t, isLoading: n } =
|
|
443
|
+
function Je(e) {
|
|
444
|
+
let { metadata: t, isLoading: n } = K(e);
|
|
426
445
|
return {
|
|
427
|
-
columns:
|
|
446
|
+
columns: A(() => t ? e.mode === "build" ? De(t.columns, {
|
|
428
447
|
resolveHeader: e.resolveHeader,
|
|
429
448
|
resolveFormatting: e.resolveFormatting
|
|
430
|
-
}) :
|
|
431
|
-
defaultColumnVisibility:
|
|
449
|
+
}) : Oe(e.columns, t.columns) : e.mode === "build" ? [] : [...e.columns], [e, t]),
|
|
450
|
+
defaultColumnVisibility: A(() => {
|
|
432
451
|
if (!t) return;
|
|
433
|
-
if (e.mode === "build") return
|
|
434
|
-
let n =
|
|
435
|
-
return
|
|
452
|
+
if (e.mode === "build") return Ee(t.columns, { resolveVisible: e.resolveVisible });
|
|
453
|
+
let n = Ee(t.columns);
|
|
454
|
+
return qe(e.columns, n);
|
|
436
455
|
}, [e, t]),
|
|
437
456
|
metadata: t,
|
|
438
457
|
isLoading: n
|
|
@@ -440,16 +459,16 @@ function Ge(e) {
|
|
|
440
459
|
}
|
|
441
460
|
//#endregion
|
|
442
461
|
//#region src/odata/odataFetchFnDev.ts
|
|
443
|
-
function
|
|
462
|
+
function Ye() {
|
|
444
463
|
return globalThis.console;
|
|
445
464
|
}
|
|
446
|
-
function
|
|
465
|
+
function Xe(e) {
|
|
447
466
|
let t = {};
|
|
448
467
|
return new Headers(e).forEach((e, n) => {
|
|
449
468
|
t[n] = e;
|
|
450
469
|
}), t;
|
|
451
470
|
}
|
|
452
|
-
function
|
|
471
|
+
function Ze(e) {
|
|
453
472
|
if (e != null) {
|
|
454
473
|
if (typeof e != "string") return e;
|
|
455
474
|
try {
|
|
@@ -459,32 +478,32 @@ function Je(e) {
|
|
|
459
478
|
}
|
|
460
479
|
}
|
|
461
480
|
}
|
|
462
|
-
function
|
|
481
|
+
function Qe(e) {
|
|
463
482
|
return e !== void 0 && !["GET", "HEAD"].includes(e.toUpperCase());
|
|
464
483
|
}
|
|
465
|
-
function
|
|
484
|
+
function $e(e) {
|
|
466
485
|
return (e.baseUrl ?? "odata") !== "" || e.path.startsWith("/sap/") || e.path.startsWith("/sap-dp0/");
|
|
467
486
|
}
|
|
468
|
-
function
|
|
487
|
+
function et(e, t) {
|
|
469
488
|
let n = t.toLowerCase();
|
|
470
489
|
return Object.keys(e).some((e) => e.toLowerCase() === n);
|
|
471
490
|
}
|
|
472
491
|
function Z(e, t, n) {
|
|
473
|
-
|
|
492
|
+
et(e, t) || (e[t] = n);
|
|
474
493
|
}
|
|
475
|
-
function
|
|
476
|
-
let t =
|
|
477
|
-
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"),
|
|
494
|
+
function tt(e) {
|
|
495
|
+
let t = Xe(e.init.headers), n = e.init.method, r = $e(e);
|
|
496
|
+
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"), Qe(n) && e.init.body && Z(t, "Content-Type", "application/json"), Qe(n) && r && Z(t, "x-csrf-token", "<получается отдельным GET перед реальным write-запросом>"), t;
|
|
478
497
|
}
|
|
479
|
-
function
|
|
480
|
-
return
|
|
498
|
+
function nt(e) {
|
|
499
|
+
return ce(e) ? "FunctionImport" : e.result ? "Parameterized Entity" : "Entity";
|
|
481
500
|
}
|
|
482
501
|
function Q(e, t) {
|
|
483
|
-
let n =
|
|
502
|
+
let n = Ye();
|
|
484
503
|
n.groupCollapsed(e), n.info(t), n.groupEnd();
|
|
485
504
|
}
|
|
486
|
-
function
|
|
487
|
-
let t =
|
|
505
|
+
function rt(e) {
|
|
506
|
+
let t = Ye(), n = Ze(e.request.init.body), r = Xe(e.request.init.headers), i = tt(e.request), a = {
|
|
488
507
|
method: e.request.init.method,
|
|
489
508
|
headers: r,
|
|
490
509
|
body: n,
|
|
@@ -494,7 +513,7 @@ function et(e) {
|
|
|
494
513
|
helper: e.helperName,
|
|
495
514
|
operation: e.operation,
|
|
496
515
|
target: e.odata.target,
|
|
497
|
-
targetKind:
|
|
516
|
+
targetKind: nt(e.target),
|
|
498
517
|
service: e.odata.service,
|
|
499
518
|
realFetch: "не выполнялся"
|
|
500
519
|
}]), 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" ? {
|
|
@@ -502,34 +521,34 @@ function et(e) {
|
|
|
502
521
|
totalCount: 0
|
|
503
522
|
} : { 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();
|
|
504
523
|
}
|
|
505
|
-
function
|
|
506
|
-
|
|
524
|
+
function it(e) {
|
|
525
|
+
Ae.warning(`${e}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, { title: "OData DEV helper" });
|
|
507
526
|
}
|
|
508
527
|
function $(t, n, r) {
|
|
509
528
|
let { odata: i, options: a = {}, init: o = {}, autoParse: s, swCache: c } = n, l = n.params ?? {};
|
|
510
529
|
return async ({ client: u, signal: d }) => {
|
|
511
|
-
|
|
512
|
-
let f = e(i.service, a.baseUrl), p = await
|
|
530
|
+
it(r);
|
|
531
|
+
let f = e(i.service, a.baseUrl), p = await T({
|
|
513
532
|
service: i.service,
|
|
514
533
|
baseUrl: f
|
|
515
534
|
}, u);
|
|
516
535
|
if (!p) throw Error(`Не удалось загрузить metadata OData-сервиса '${i.service}'`);
|
|
517
|
-
let m =
|
|
518
|
-
|
|
519
|
-
let h =
|
|
536
|
+
let m = he(p, i.target);
|
|
537
|
+
fe(m, t, i);
|
|
538
|
+
let h = ie(n.body, t), g = ae(m, t), _ = re(m, i, l, t), v = c ? {
|
|
520
539
|
...a,
|
|
521
540
|
baseUrl: f,
|
|
522
541
|
swCache: c
|
|
523
542
|
} : {
|
|
524
543
|
...a,
|
|
525
544
|
baseUrl: f
|
|
526
|
-
}, y =
|
|
545
|
+
}, y = ne(_, v, {
|
|
527
546
|
...o,
|
|
528
547
|
method: g,
|
|
529
548
|
body: h,
|
|
530
549
|
signal: d
|
|
531
550
|
});
|
|
532
|
-
return
|
|
551
|
+
return rt({
|
|
533
552
|
helperName: r,
|
|
534
553
|
operation: t,
|
|
535
554
|
odata: i,
|
|
@@ -548,25 +567,25 @@ function $(t, n, r) {
|
|
|
548
567
|
} : { data: void 0 };
|
|
549
568
|
};
|
|
550
569
|
}
|
|
551
|
-
function nt(e) {
|
|
552
|
-
return __DEV__ ? $("create", e, "odataCreateFnDev") : w("create", e);
|
|
553
|
-
}
|
|
554
|
-
function rt(e) {
|
|
555
|
-
return __DEV__ ? $("update", e, "odataUpdateFnDev") : w("update", e);
|
|
556
|
-
}
|
|
557
|
-
function it(e) {
|
|
558
|
-
return __DEV__ ? $("delete", e, "odataDeleteFnDev") : w("delete", e);
|
|
559
|
-
}
|
|
560
570
|
function at(e) {
|
|
561
|
-
return __DEV__ ? $("
|
|
571
|
+
return __DEV__ ? $("create", e, "odataCreateFnDev") : E("create", e);
|
|
562
572
|
}
|
|
563
573
|
function ot(e) {
|
|
564
|
-
return __DEV__ ? $("
|
|
574
|
+
return __DEV__ ? $("update", e, "odataUpdateFnDev") : E("update", e);
|
|
565
575
|
}
|
|
566
576
|
function st(e) {
|
|
567
|
-
return __DEV__ ? $("
|
|
577
|
+
return __DEV__ ? $("delete", e, "odataDeleteFnDev") : E("delete", e);
|
|
578
|
+
}
|
|
579
|
+
function ct(e) {
|
|
580
|
+
return __DEV__ ? $("read", e, "odataReadFnDev") : E("read", e);
|
|
581
|
+
}
|
|
582
|
+
function lt(e) {
|
|
583
|
+
return __DEV__ ? $("query", e, "odataQueryFnDev") : E("query", e);
|
|
584
|
+
}
|
|
585
|
+
function ut(e) {
|
|
586
|
+
return __DEV__ ? $("fi", e, "odataFunctionImportFnDev") : E("fi", e);
|
|
568
587
|
}
|
|
569
588
|
//#endregion
|
|
570
|
-
export { h as BaseAppConfigURL, f as BaseODataDp0URL, l as BaseODataUI2URL, c as BaseODataURL, n as BaseUrlMap,
|
|
589
|
+
export { h as BaseAppConfigURL, f as BaseODataDp0URL, l as BaseODataUI2URL, c as BaseODataURL, n as BaseUrlMap, z as ODATA_COLLECTION_BUST_SW_CACHE, R as ODATA_COLLECTION_DEFAULT_SW_CACHE, L as ODATA_COLLECTION_UPDATES_LOOKBACK_MS, B as ODATA_COLLECTION_UPDATES_SW_CACHE, d as SsoRequiredError, le as applyODataMetadataVersion, i as configureODataProjectAdapter, Me as createODataCollectionBaseQueryKey, F as createODataCollectionQueryKey, V as createODataCollectionUpdatesQueryKey, v as fetchBase, p as fetchDeleteFn, g as fetchJson, u as fetchJsonMutationFn, r as fetchJsonQueryFn, oe as fetchMetadata, U as fetchODataCollectionUpdates, m as fetchODataJson, _ as fetchQueryFn, Ne as flattenODataDependentServices, b as getInputUrl, T as getODataMetadataData, S as getODataProjectAdapter, a as isNoContentResponse, y as isSsoForm, t as normalizeODataServiceName, C as normalizeRelativePath, W as odataCollectionUpdatesQueryOptions, me as odataCreateFn, at as odataCreateFnDev, ue as odataDeleteFn, st as odataDeleteFnDev, D as odataFetch, se as odataFunctionImportFn, ut as odataFunctionImportFnDev, ee as odataMetadataQueryOptions, te as odataQueryFn, lt as odataQueryFnDev, de as odataReadFn, ct as odataReadFnDev, pe as odataUpdateFn, ot as odataUpdateFnDev, o as recoverSsoSession, e as resolveODataBaseUrl, Y as resolveODataCollectionSwCachePolicy, x as resolveODataSapClient, He as shouldRefreshODataCollectionCache, Pe as sortODataDependentSegmentItemsByChains, Ie as sortODataDependentServicesByChains, s as submitSsoForm, We as useODataCollection, Ge as useODataCollectionChains, Ke as useODataCollectionModel, Ue as useODataCollectionQuery, G as useODataCollectionUpdatesQuery, J as useODataEntity, K as useODataMetadata, ge as useODataMetadataQuery, _e as useODataMetadataVersionQuery, Je as useODataTableColumns };
|
|
571
590
|
|
|
572
591
|
//# sourceMappingURL=index.js.map
|
package/dist/odata/index.js.map
CHANGED
|
@@ -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/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 { 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 * Разделяет одну text-проекцию между всеми observer одного Query snapshot.\n *\n * WeakMap не удерживает выгруженный Query в памяти. Пока snapshot активен,\n * дополнительные ракурсы переиспользуют уже отсортированные массивы ссылок\n * вместо повторной сортировки и отдельной копии массивов для каждого observer.\n */\nconst textProjectionBySource = new WeakMap<ODataCollectionResult<CollectionItem>, ODataCollectionResult<CollectionItem>>();\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\tconst cachedProjection = textProjectionBySource.get(source);\n\tif (cachedProjection) {\n\t\treturn cachedProjection as ODataCollectionResult<T>;\n\t}\n\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\tconst projection = {\n\t\t...source,\n\t\tseparated\n\t};\n\ttextProjectionBySource.set(source, projection);\n\n\treturn projection;\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;AAW5E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,cAAc,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CA8BrI"}
|
package/dist/odata/types.d.ts
CHANGED
|
@@ -21,7 +21,12 @@ export interface ODataCollectionConfig extends ODataServiceCollectionConfig {
|
|
|
21
21
|
*/
|
|
22
22
|
excludeEmpty?: true;
|
|
23
23
|
/**
|
|
24
|
-
* Сортировка
|
|
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":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AAE1G;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhE,MAAM,WAAW,4BAA6B,SAAQ,kBAAkB;IACvE;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEhC,YAAY,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,qBAAsB,SAAQ,4BAA4B;IAC1E;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB
|
|
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;
|
|
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"}
|