@ryuzaki13/react-foundation-api 1.0.0

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.
Files changed (166) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/adt/fetchUserTransports.d.ts +2 -0
  4. package/dist/adt/fetchUserTransports.d.ts.map +1 -0
  5. package/dist/adt/index.d.ts +4 -0
  6. package/dist/adt/index.d.ts.map +1 -0
  7. package/dist/adt/index.js +70 -0
  8. package/dist/adt/index.js.map +1 -0
  9. package/dist/adt/parseUserTransportsXml.d.ts +3 -0
  10. package/dist/adt/parseUserTransportsXml.d.ts.map +1 -0
  11. package/dist/adt/types.d.ts +10 -0
  12. package/dist/adt/types.d.ts.map +1 -0
  13. package/dist/async/AsyncTasksError.d.ts +6 -0
  14. package/dist/async/AsyncTasksError.d.ts.map +1 -0
  15. package/dist/async/ConcurrencyPartialError.d.ts +6 -0
  16. package/dist/async/ConcurrencyPartialError.d.ts.map +1 -0
  17. package/dist/async/index.d.ts +5 -0
  18. package/dist/async/index.d.ts.map +1 -0
  19. package/dist/async/index.js +163 -0
  20. package/dist/async/index.js.map +1 -0
  21. package/dist/async/runAsyncTasks.d.ts +32 -0
  22. package/dist/async/runAsyncTasks.d.ts.map +1 -0
  23. package/dist/async/runConcurrentTasks.d.ts +127 -0
  24. package/dist/async/runConcurrentTasks.d.ts.map +1 -0
  25. package/dist/chunks/fetch-BW2OtCu7.js +508 -0
  26. package/dist/chunks/fetch-BW2OtCu7.js.map +1 -0
  27. package/dist/chunks/odata-ZgZGme_K.js +473 -0
  28. package/dist/chunks/odata-ZgZGme_K.js.map +1 -0
  29. package/dist/chunks/odataFetchFn-BXVJxOou.js +302 -0
  30. package/dist/chunks/odataFetchFn-BXVJxOou.js.map +1 -0
  31. package/dist/error-report/errorReport.d.ts +28 -0
  32. package/dist/error-report/errorReport.d.ts.map +1 -0
  33. package/dist/error-report/index.d.ts +2 -0
  34. package/dist/error-report/index.d.ts.map +1 -0
  35. package/dist/error-report/index.js +42 -0
  36. package/dist/error-report/index.js.map +1 -0
  37. package/dist/http/RouteError.d.ts +5 -0
  38. package/dist/http/RouteError.d.ts.map +1 -0
  39. package/dist/http/http.d.ts +20 -0
  40. package/dist/http/http.d.ts.map +1 -0
  41. package/dist/http/index.d.ts +4 -0
  42. package/dist/http/index.d.ts.map +1 -0
  43. package/dist/http/index.js +67 -0
  44. package/dist/http/index.js.map +1 -0
  45. package/dist/http/types.d.ts +23 -0
  46. package/dist/http/types.d.ts.map +1 -0
  47. package/dist/odata/createODataCollectionQueryKey.d.ts +9 -0
  48. package/dist/odata/createODataCollectionQueryKey.d.ts.map +1 -0
  49. package/dist/odata/fetchCollectionData.d.ts +15 -0
  50. package/dist/odata/fetchCollectionData.d.ts.map +1 -0
  51. package/dist/odata/flattenODataDependentServices.d.ts +6 -0
  52. package/dist/odata/flattenODataDependentServices.d.ts.map +1 -0
  53. package/dist/odata/index.d.ts +21 -0
  54. package/dist/odata/index.d.ts.map +1 -0
  55. package/dist/odata/index.js +4 -0
  56. package/dist/odata/metadataVersionCheck.d.ts +49 -0
  57. package/dist/odata/metadataVersionCheck.d.ts.map +1 -0
  58. package/dist/odata/odataBaseQueryKey.d.ts +2 -0
  59. package/dist/odata/odataBaseQueryKey.d.ts.map +1 -0
  60. package/dist/odata/odataFetch.d.ts +87 -0
  61. package/dist/odata/odataFetch.d.ts.map +1 -0
  62. package/dist/odata/odataFetchFn.d.ts +399 -0
  63. package/dist/odata/odataFetchFn.d.ts.map +1 -0
  64. package/dist/odata/odataFetchFnDev.d.ts +58 -0
  65. package/dist/odata/odataFetchFnDev.d.ts.map +1 -0
  66. package/dist/odata/odataFetchFnHelpers.d.ts +9 -0
  67. package/dist/odata/odataFetchFnHelpers.d.ts.map +1 -0
  68. package/dist/odata/odataProjectAdapter.d.ts +22 -0
  69. package/dist/odata/odataProjectAdapter.d.ts.map +1 -0
  70. package/dist/odata/parseODataResponseByMetadata.d.ts +4 -0
  71. package/dist/odata/parseODataResponseByMetadata.d.ts.map +1 -0
  72. package/dist/odata/sortODataDependentSegmentItemsByChains.d.ts +8 -0
  73. package/dist/odata/sortODataDependentSegmentItemsByChains.d.ts.map +1 -0
  74. package/dist/odata/sortODataDependentServicesByChains.d.ts +12 -0
  75. package/dist/odata/sortODataDependentServicesByChains.d.ts.map +1 -0
  76. package/dist/odata/transport/SsoRequiredError.d.ts +22 -0
  77. package/dist/odata/transport/SsoRequiredError.d.ts.map +1 -0
  78. package/dist/odata/transport/errorReport.d.ts +3 -0
  79. package/dist/odata/transport/errorReport.d.ts.map +1 -0
  80. package/dist/odata/transport/fetch.d.ts +43 -0
  81. package/dist/odata/transport/fetch.d.ts.map +1 -0
  82. package/dist/odata/transport/index.d.ts +5 -0
  83. package/dist/odata/transport/index.d.ts.map +1 -0
  84. package/dist/odata/transport/types.d.ts +12 -0
  85. package/dist/odata/transport/types.d.ts.map +1 -0
  86. package/dist/odata/transport/url.d.ts +13 -0
  87. package/dist/odata/transport/url.d.ts.map +1 -0
  88. package/dist/odata/types.d.ts +176 -0
  89. package/dist/odata/types.d.ts.map +1 -0
  90. package/dist/odata/useODataCollection.d.ts +39 -0
  91. package/dist/odata/useODataCollection.d.ts.map +1 -0
  92. package/dist/odata/useODataCollectionChains.d.ts +7 -0
  93. package/dist/odata/useODataCollectionChains.d.ts.map +1 -0
  94. package/dist/odata/useODataCollectionModel.d.ts +3 -0
  95. package/dist/odata/useODataCollectionModel.d.ts.map +1 -0
  96. package/dist/odata/useODataCollectionQuery.d.ts +34 -0
  97. package/dist/odata/useODataCollectionQuery.d.ts.map +1 -0
  98. package/dist/odata/useODataCollectionUpdatesQuery.d.ts +51 -0
  99. package/dist/odata/useODataCollectionUpdatesQuery.d.ts.map +1 -0
  100. package/dist/odata/useODataEntity.d.ts +28 -0
  101. package/dist/odata/useODataEntity.d.ts.map +1 -0
  102. package/dist/odata/useODataMetadata.d.ts +13 -0
  103. package/dist/odata/useODataMetadata.d.ts.map +1 -0
  104. package/dist/odata/useODataMetadataQuery.d.ts +32 -0
  105. package/dist/odata/useODataMetadataQuery.d.ts.map +1 -0
  106. package/dist/odata/useODataTableColumns.d.ts +69 -0
  107. package/dist/odata/useODataTableColumns.d.ts.map +1 -0
  108. package/dist/odata/useTextServiceQuery.d.ts +3 -0
  109. package/dist/odata/useTextServiceQuery.d.ts.map +1 -0
  110. package/dist/persisted/cache.d.ts +29 -0
  111. package/dist/persisted/cache.d.ts.map +1 -0
  112. package/dist/persisted/index.d.ts +22 -0
  113. package/dist/persisted/index.d.ts.map +1 -0
  114. package/dist/persisted/index.js +339 -0
  115. package/dist/persisted/index.js.map +1 -0
  116. package/dist/persisted/keys.d.ts +21 -0
  117. package/dist/persisted/keys.d.ts.map +1 -0
  118. package/dist/persisted/odata.d.ts +113 -0
  119. package/dist/persisted/odata.d.ts.map +1 -0
  120. package/dist/persisted/payload.d.ts +29 -0
  121. package/dist/persisted/payload.d.ts.map +1 -0
  122. package/dist/persisted/resource.d.ts +87 -0
  123. package/dist/persisted/resource.d.ts.map +1 -0
  124. package/dist/persisted/rest.d.ts +87 -0
  125. package/dist/persisted/rest.d.ts.map +1 -0
  126. package/dist/persisted/types.d.ts +172 -0
  127. package/dist/persisted/types.d.ts.map +1 -0
  128. package/dist/resource/cache.d.ts +22 -0
  129. package/dist/resource/cache.d.ts.map +1 -0
  130. package/dist/resource/index.d.ts +5 -0
  131. package/dist/resource/index.d.ts.map +1 -0
  132. package/dist/resource/index.js +147 -0
  133. package/dist/resource/index.js.map +1 -0
  134. package/dist/resource/keys.d.ts +14 -0
  135. package/dist/resource/keys.d.ts.map +1 -0
  136. package/dist/resource/resource.d.ts +38 -0
  137. package/dist/resource/resource.d.ts.map +1 -0
  138. package/dist/resource/types.d.ts +112 -0
  139. package/dist/resource/types.d.ts.map +1 -0
  140. package/dist/s3/constants.d.ts +12 -0
  141. package/dist/s3/constants.d.ts.map +1 -0
  142. package/dist/s3/fetchFileFromS3.d.ts +13 -0
  143. package/dist/s3/fetchFileFromS3.d.ts.map +1 -0
  144. package/dist/s3/index.d.ts +3 -0
  145. package/dist/s3/index.d.ts.map +1 -0
  146. package/dist/s3/index.js +41 -0
  147. package/dist/s3/index.js.map +1 -0
  148. package/dist/s3/uploadToS3.d.ts +18 -0
  149. package/dist/s3/uploadToS3.d.ts.map +1 -0
  150. package/dist/server-fn/index.d.ts +2 -0
  151. package/dist/server-fn/index.d.ts.map +1 -0
  152. package/dist/server-fn/index.js +37 -0
  153. package/dist/server-fn/index.js.map +1 -0
  154. package/dist/server-fn/serverFn.d.ts +64 -0
  155. package/dist/server-fn/serverFn.d.ts.map +1 -0
  156. package/dist/transport/fetchTransportRequests.d.ts +11 -0
  157. package/dist/transport/fetchTransportRequests.d.ts.map +1 -0
  158. package/dist/transport/index.d.ts +4 -0
  159. package/dist/transport/index.d.ts.map +1 -0
  160. package/dist/transport/index.js +52 -0
  161. package/dist/transport/index.js.map +1 -0
  162. package/dist/transport/normalizeTransportRequests.d.ts +3 -0
  163. package/dist/transport/normalizeTransportRequests.d.ts.map +1 -0
  164. package/dist/transport/types.d.ts +19 -0
  165. package/dist/transport/types.d.ts.map +1 -0
  166. package/package.json +202 -0
@@ -0,0 +1,29 @@
1
+ import type { PersistedCacheStrategy, PersistedCacheStrategyContext, PersistedSetQueryDataStrategyOptions } from "./types";
2
+ /**
3
+ * Безопасно применяет cache strategy, если она была передана.
4
+ */
5
+ export declare function applyPersistedCacheStrategy<TScope, TInput, TResult>(strategy: PersistedCacheStrategy<TScope, TInput, TResult> | null | undefined, context: PersistedCacheStrategyContext<TScope, TInput, TResult>): Promise<void>;
6
+ /**
7
+ * Создаёт стратегию, инвалидирующую все query внутри одного scope.
8
+ *
9
+ * Это рекомендуемый default для ресурсов, где мутация может затронуть сразу
10
+ * несколько представлений данных: `list`, `latest`, `history`.
11
+ */
12
+ export declare function createInvalidatePersistedScopeCacheStrategy<TScope, TInput, TResult>(): PersistedCacheStrategy<TScope, TInput, TResult>;
13
+ /**
14
+ * Создаёт стратегию точечного обновления одного query через `setQueryData`.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const strategy = createSetPersistedQueryDataCacheStrategy({
19
+ * getQueryKey: ({ descriptor, scope }) => descriptor.keys.latest(scope),
20
+ * update: (_, { result }) => result
21
+ * });
22
+ * ```
23
+ */
24
+ export declare function createSetPersistedQueryDataCacheStrategy<TScope, TInput, TResult, TData>(options: PersistedSetQueryDataStrategyOptions<TScope, TInput, TResult, TData>): PersistedCacheStrategy<TScope, TInput, TResult>;
25
+ /**
26
+ * Комбинирует несколько cache strategy в одну последовательную стратегию.
27
+ */
28
+ export declare function composePersistedCacheStrategies<TScope, TInput, TResult>(...strategies: Array<PersistedCacheStrategy<TScope, TInput, TResult> | null | undefined>): PersistedCacheStrategy<TScope, TInput, TResult>;
29
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/persisted/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,oCAAoC,EAAE,MAAM,SAAS,CAAC;AAE3H;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EACxE,QAAQ,EAAE,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC5E,OAAO,EAAE,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,iBAG/D;AAED;;;;;GAKG;AACH,wBAAgB,2CAA2C,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAMtI;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wCAAwC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EACtF,OAAO,EAAE,oCAAoC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,GAC3E,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAQjD;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EACtE,GAAG,UAAU,EAAE,KAAK,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GACtF,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAQjD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Внутренний infrastructural-модуль для persisted ресурсов.
3
+ *
4
+ * Этот слой собирает повторяющуюся механику вокруг API сохранённых записей:
5
+ * - JSON payload codec;
6
+ * - фабрики query key;
7
+ * - capability-based descriptor ресурса;
8
+ * - адаптеры под OData и REST;
9
+ * - общие query/mutation-хуки;
10
+ * - стратегии синхронизации react-query кэша.
11
+ *
12
+ * Модуль не содержит доменной бизнес-логики и не знает ничего про конкретные
13
+ * сущности вроде variant, view-config или preset.
14
+ */
15
+ export * from "./cache";
16
+ export * from "./keys";
17
+ export * from "./odata";
18
+ export * from "./payload";
19
+ export * from "./resource";
20
+ export * from "./rest";
21
+ export * from "./types";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persisted/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,339 @@
1
+ import { httpFetchPayload as e } from "../http/index.js";
2
+ import { r as t } from "../chunks/odataFetchFn-BXVJxOou.js";
3
+ import { createResourceKeys as n } from "../resource/index.js";
4
+ import { queryOptions as r, useMutation as i, useQuery as a, useQueryClient as o } from "@tanstack/react-query";
5
+ //#region src/persisted/cache.ts
6
+ async function s(e, t) {
7
+ await e?.onSuccess?.(t);
8
+ }
9
+ function c() {
10
+ return { onSuccess: async ({ client: e, descriptor: t, scope: n }) => {
11
+ await e.invalidateQueries({ queryKey: t.keys.scope(n) });
12
+ } };
13
+ }
14
+ function l(e) {
15
+ return { onSuccess: ({ client: t, ...n }) => {
16
+ t.setQueryData(e.getQueryKey({
17
+ client: t,
18
+ ...n
19
+ }), (r) => e.update(r, {
20
+ client: t,
21
+ ...n
22
+ }));
23
+ } };
24
+ }
25
+ function u(...e) {
26
+ return { onSuccess: async (t) => {
27
+ for (let n of e) await n?.onSuccess?.(t);
28
+ } };
29
+ }
30
+ //#endregion
31
+ //#region src/persisted/keys.ts
32
+ function d(e) {
33
+ let t = n(e);
34
+ return {
35
+ ...t,
36
+ list: (e) => t.operation("list", e),
37
+ latest: (e) => t.operation("latest", e),
38
+ history: (e, n) => t.operation("history", e, n),
39
+ save: (e) => t.operation("save", e),
40
+ create: (e) => t.operation("create", e),
41
+ delete: (e) => t.operation("delete", e)
42
+ };
43
+ }
44
+ //#endregion
45
+ //#region src/persisted/odata.ts
46
+ async function f(e, n, r, i) {
47
+ if (i) return await i(e, n, r);
48
+ switch (e) {
49
+ case "query": return await t("query", n)(r);
50
+ case "create": return await t("create", n)(r);
51
+ case "update": return await t("update", n)(r);
52
+ case "delete": return await t("delete", n)(r);
53
+ case "read": return await t("read", n)(r);
54
+ case "fi": return await t("fi", n)(r);
55
+ }
56
+ }
57
+ function p(e) {
58
+ return {
59
+ isEnabled: e.isEnabled,
60
+ staleTime: e.staleTime,
61
+ gcTime: e.gcTime,
62
+ meta: e.meta,
63
+ execute: async ({ scope: t, args: n, client: r, signal: i }) => {
64
+ let a = await f("query", {
65
+ odata: e.odata,
66
+ params: e.buildParams?.(t, n),
67
+ options: {
68
+ baseUrl: e.baseUrl,
69
+ ...e.buildOptions?.(t, n)
70
+ },
71
+ init: e.buildInit?.(t, n)
72
+ }, {
73
+ client: r,
74
+ signal: i
75
+ }, e.executor);
76
+ return e.transform ? e.transform(a.data, {
77
+ scope: t,
78
+ args: n
79
+ }) : a.data;
80
+ }
81
+ };
82
+ }
83
+ function m(e) {
84
+ return {
85
+ isEnabled: e.isEnabled,
86
+ staleTime: e.staleTime,
87
+ gcTime: e.gcTime,
88
+ meta: e.meta,
89
+ execute: async ({ scope: t, args: n, client: r, signal: i }) => {
90
+ let a = await f("read", {
91
+ odata: e.odata,
92
+ params: e.buildParams?.(t, n),
93
+ options: {
94
+ baseUrl: e.baseUrl,
95
+ ...e.buildOptions?.(t, n)
96
+ },
97
+ init: e.buildInit?.(t, n)
98
+ }, {
99
+ client: r,
100
+ signal: i
101
+ }, e.executor);
102
+ return e.transform ? e.transform(a.data, {
103
+ scope: t,
104
+ args: n
105
+ }) : a.data;
106
+ }
107
+ };
108
+ }
109
+ function h(e) {
110
+ return {
111
+ cacheStrategy: e.cacheStrategy,
112
+ execute: async ({ scope: t, input: n, client: r }) => {
113
+ let i = e.method === "delete" ? await f(e.method, {
114
+ odata: e.odata,
115
+ params: e.buildParams(t, n),
116
+ options: {
117
+ baseUrl: e.baseUrl,
118
+ ...e.buildOptions?.(t, n)
119
+ },
120
+ init: e.buildInit?.(t, n)
121
+ }, { client: r }, e.executor) : e.method === "update" ? await f(e.method, {
122
+ odata: e.odata,
123
+ params: e.buildParams(t, n),
124
+ body: e.bodyMapper(t, n),
125
+ options: {
126
+ baseUrl: e.baseUrl,
127
+ ...e.buildOptions?.(t, n)
128
+ },
129
+ init: e.buildInit?.(t, n)
130
+ }, { client: r }, e.executor) : await f(e.method, {
131
+ odata: e.odata,
132
+ body: e.bodyMapper(t, n),
133
+ options: {
134
+ baseUrl: e.baseUrl,
135
+ ...e.buildOptions?.(t, n)
136
+ },
137
+ init: e.buildInit?.(t, n)
138
+ }, { client: r }, e.executor);
139
+ return e.transform ? e.transform(i.data, {
140
+ scope: t,
141
+ input: n
142
+ }) : i.data;
143
+ }
144
+ };
145
+ }
146
+ //#endregion
147
+ //#region src/persisted/payload.ts
148
+ function g(e) {
149
+ if (!e) return null;
150
+ try {
151
+ return JSON.parse(e);
152
+ } catch {
153
+ return null;
154
+ }
155
+ }
156
+ function _(e) {
157
+ return JSON.stringify(e);
158
+ }
159
+ function v() {
160
+ return {
161
+ parse: g,
162
+ stringify: _
163
+ };
164
+ }
165
+ //#endregion
166
+ //#region src/persisted/resource.ts
167
+ function y(e, t) {
168
+ if (t != null && (e.isEnabled?.(t) ?? !0)) return t;
169
+ throw Error(e.getScopeError?.(t) ?? "Недостаточно данных scope для persisted-record ресурса.");
170
+ }
171
+ function b(e, t) {
172
+ let n = e.transport[t];
173
+ if (!n) throw Error(`Persisted-record ресурс '${e.resource}' не поддерживает операцию '${t}'.`);
174
+ return n;
175
+ }
176
+ function x(e, t) {
177
+ let n = e.transport[t];
178
+ if (!n) throw Error(`Persisted-record ресурс '${e.resource}' не поддерживает операцию '${t}'.`);
179
+ return n;
180
+ }
181
+ function S(e, t, n, r) {
182
+ return e.keys.operation(t, n, r);
183
+ }
184
+ function C(e, t, n, r) {
185
+ return e.isEnabled?.(n) ?? !0 ? t.isEnabled?.(n, r) ?? !0 : !1;
186
+ }
187
+ function w(e, t, n, i) {
188
+ let a = b(e, t), o = C(e, a, n, i);
189
+ return r({
190
+ queryKey: S(e, t, n, i),
191
+ queryFn: ({ client: t, signal: r }) => {
192
+ let o = y(e, n);
193
+ return a.execute({
194
+ scope: o,
195
+ args: i,
196
+ client: t,
197
+ signal: r
198
+ });
199
+ },
200
+ enabled: o,
201
+ staleTime: a.staleTime,
202
+ gcTime: a.gcTime,
203
+ meta: a.meta
204
+ });
205
+ }
206
+ function T(e, t, n, r) {
207
+ return a(w(e, t, n, r));
208
+ }
209
+ async function E(e, t, n, r, i) {
210
+ return await i.fetchQuery(w(e, t, n, r));
211
+ }
212
+ function D(e, t, n, r) {
213
+ let a = o(), c = x(e, t);
214
+ return i({
215
+ mutationKey: S(e, t, n),
216
+ mutationFn: async (t) => {
217
+ let r = y(e, n);
218
+ return await c.execute({
219
+ scope: r,
220
+ input: t,
221
+ client: a
222
+ });
223
+ },
224
+ onSuccess: async (t, i) => {
225
+ let o = y(e, n);
226
+ await s(r?.cacheStrategy === void 0 ? c.cacheStrategy : r.cacheStrategy, {
227
+ client: a,
228
+ descriptor: e,
229
+ scope: o,
230
+ input: i,
231
+ result: t
232
+ }), await r?.onSuccess?.(t, i);
233
+ }
234
+ });
235
+ }
236
+ function O(e) {
237
+ return {
238
+ namespace: e.namespace,
239
+ resource: e.resource,
240
+ keys: d({
241
+ namespace: e.namespace,
242
+ resource: e.resource,
243
+ normalizeScope: e.normalizeScope
244
+ }),
245
+ transport: e.transport,
246
+ isEnabled: e.isEnabled,
247
+ getScopeError: e.getScopeError
248
+ };
249
+ }
250
+ function k(e, t) {
251
+ return T(e, "list", t, void 0);
252
+ }
253
+ function A(e, t) {
254
+ return T(e, "latest", t, void 0);
255
+ }
256
+ function j(e, t, n) {
257
+ return T(e, "history", t, n);
258
+ }
259
+ async function M(e, t, n) {
260
+ return await E(e, "list", t, void 0, n);
261
+ }
262
+ async function N(e, t, n) {
263
+ return await E(e, "latest", t, void 0, n);
264
+ }
265
+ async function P(e, t, n, r) {
266
+ return await E(e, "history", t, n, r);
267
+ }
268
+ function F(e, t, n) {
269
+ return D(e, "save", t, n);
270
+ }
271
+ function I(e, t, n) {
272
+ return D(e, "create", t, n);
273
+ }
274
+ function L(e, t, n) {
275
+ return D(e, "delete", t, n);
276
+ }
277
+ //#endregion
278
+ //#region src/persisted/rest.ts
279
+ async function R(t, n) {
280
+ if (n.executor) return await n.executor(t);
281
+ if (!n.parseResponse) throw Error("REST persisted operation requires executor or parseResponse.");
282
+ let r = await e(t.url, {
283
+ baseUrl: t.baseUrl,
284
+ init: t.init
285
+ });
286
+ return n.parseResponse(r);
287
+ }
288
+ function z(e) {
289
+ return {
290
+ isEnabled: e.isEnabled,
291
+ staleTime: e.staleTime,
292
+ gcTime: e.gcTime,
293
+ execute: async ({ scope: t, args: n, signal: r }) => {
294
+ let i = await R({
295
+ url: e.buildUrl(t, n),
296
+ baseUrl: e.baseUrl,
297
+ init: {
298
+ ...e.buildInit?.(t, n),
299
+ signal: r
300
+ }
301
+ }, {
302
+ executor: e.executor,
303
+ parseResponse: e.parseResponse
304
+ });
305
+ return "transform" in e ? e.transform(i, {
306
+ scope: t,
307
+ args: n
308
+ }) : i;
309
+ }
310
+ };
311
+ }
312
+ function B(e) {
313
+ return {
314
+ cacheStrategy: e.cacheStrategy,
315
+ execute: async ({ scope: t, input: n }) => {
316
+ let r = e.bodyMapper?.(t, n), i = await R({
317
+ url: e.buildUrl(t, n),
318
+ baseUrl: e.baseUrl,
319
+ init: {
320
+ method: e.method,
321
+ headers: r === void 0 ? void 0 : { "Content-Type": "application/json" },
322
+ ...e.buildInit?.(t, n),
323
+ body: r === void 0 ? void 0 : JSON.stringify(r)
324
+ }
325
+ }, {
326
+ executor: e.executor,
327
+ parseResponse: e.parseResponse
328
+ });
329
+ return "transform" in e ? e.transform(i, {
330
+ scope: t,
331
+ input: n
332
+ }) : i;
333
+ }
334
+ };
335
+ }
336
+ //#endregion
337
+ export { s as applyPersistedCacheStrategy, u as composePersistedCacheStrategies, c as createInvalidatePersistedScopeCacheStrategy, v as createPersistedJsonCodec, h as createPersistedODataMutationOperation, p as createPersistedODataQueryOperation, m as createPersistedODataReadOperation, d as createPersistedRecordKeys, O as createPersistedResourceDescriptor, B as createPersistedRestMutationOperation, z as createPersistedRestQueryOperation, l as createSetPersistedQueryDataCacheStrategy, P as getPersistedHistoryData, N as getPersistedLatestData, M as getPersistedListData, g as parsePersistedJson, _ as stringifyPersistedJson, I as usePersistedCreateMutation, L as usePersistedDeleteMutation, j as usePersistedHistoryQuery, A as usePersistedLatestQuery, k as usePersistedListQuery, F as usePersistedSaveMutation };
338
+
339
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/persisted/cache.ts","../../src/persisted/keys.ts","../../src/persisted/odata.ts","../../src/persisted/payload.ts","../../src/persisted/resource.ts","../../src/persisted/rest.ts"],"sourcesContent":["import type { PersistedCacheStrategy, PersistedCacheStrategyContext, PersistedSetQueryDataStrategyOptions } from \"./types\";\n\n/**\n * Безопасно применяет cache strategy, если она была передана.\n */\nexport async function applyPersistedCacheStrategy<TScope, TInput, TResult>(\n\tstrategy: PersistedCacheStrategy<TScope, TInput, TResult> | null | undefined,\n\tcontext: PersistedCacheStrategyContext<TScope, TInput, TResult>\n) {\n\tawait strategy?.onSuccess?.(context);\n}\n\n/**\n * Создаёт стратегию, инвалидирующую все query внутри одного scope.\n *\n * Это рекомендуемый default для ресурсов, где мутация может затронуть сразу\n * несколько представлений данных: `list`, `latest`, `history`.\n */\nexport function createInvalidatePersistedScopeCacheStrategy<TScope, TInput, TResult>(): PersistedCacheStrategy<TScope, TInput, TResult> {\n\treturn {\n\t\tonSuccess: async ({ client, descriptor, scope }) => {\n\t\t\tawait client.invalidateQueries({ queryKey: descriptor.keys.scope(scope) });\n\t\t}\n\t};\n}\n\n/**\n * Создаёт стратегию точечного обновления одного query через `setQueryData`.\n *\n * @example\n * ```ts\n * const strategy = createSetPersistedQueryDataCacheStrategy({\n * getQueryKey: ({ descriptor, scope }) => descriptor.keys.latest(scope),\n * update: (_, { result }) => result\n * });\n * ```\n */\nexport function createSetPersistedQueryDataCacheStrategy<TScope, TInput, TResult, TData>(\n\toptions: PersistedSetQueryDataStrategyOptions<TScope, TInput, TResult, TData>\n): PersistedCacheStrategy<TScope, TInput, TResult> {\n\treturn {\n\t\tonSuccess: ({ client, ...context }) => {\n\t\t\tclient.setQueryData<TData>(options.getQueryKey({ client, ...context }), (current) =>\n\t\t\t\toptions.update(current, { client, ...context })\n\t\t\t);\n\t\t}\n\t};\n}\n\n/**\n * Комбинирует несколько cache strategy в одну последовательную стратегию.\n */\nexport function composePersistedCacheStrategies<TScope, TInput, TResult>(\n\t...strategies: Array<PersistedCacheStrategy<TScope, TInput, TResult> | null | undefined>\n): PersistedCacheStrategy<TScope, TInput, TResult> {\n\treturn {\n\t\tonSuccess: async (context) => {\n\t\t\tfor (const strategy of strategies) {\n\t\t\t\tawait strategy?.onSuccess?.(context);\n\t\t\t}\n\t\t}\n\t};\n}\n","import { createResourceKeys } from \"../resource\";\n\nimport type { PersistedOperationName, PersistedRecordKeys } from \"./types\";\n\n/**\n * Создаёт фабрики query key для persisted-record ресурса.\n *\n * @example\n * ```ts\n * const keys = createPersistedRecordKeys<{ appId: string; viewId: string }>({\n * namespace: \"viewConfig\",\n * resource: \"view\"\n * });\n *\n * keys.latest({ appId: \"APP\", viewId: \"MAIN\" });\n * // => [\"viewConfig\", \"view\", { appId: \"sales\", viewId: \"CumulativeShipment\" }, \"latest\"]\n * ```\n */\nexport function createPersistedRecordKeys<TScope>(options: {\n\tnamespace: string;\n\tresource: string;\n\tnormalizeScope?: (scope: TScope | null | undefined) => unknown;\n}): PersistedRecordKeys<TScope> {\n\tconst keys = createResourceKeys<TScope, PersistedOperationName>(options);\n\n\treturn {\n\t\t...keys,\n\t\tlist: (value) => keys.operation(\"list\", value),\n\t\tlatest: (value) => keys.operation(\"latest\", value),\n\t\thistory: (value, args) => keys.operation(\"history\", value, args),\n\t\tsave: (value) => keys.operation(\"save\", value),\n\t\tcreate: (value) => keys.operation(\"create\", value),\n\t\tdelete: (value) => keys.operation(\"delete\", value)\n\t};\n}\n","import { type ODataFetchFnRequest, type ODataFetchOptions } from \"../odata\";\nimport { odataFetchFn } from \"../odata/odataFetchFn\";\nimport { BaseURLType } from \"../odata/transport\";\n\nimport { PersistedMutationOperation, PersistedQueryOperation } from \"./types\";\n\nimport type { ODataOperationMethod, ODataServiceConfig, WrappedODataParameters } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport type { QueryClient, QueryMeta } from \"@tanstack/react-query\";\n\n/**\n * Полная сигнатура конфигурации `odataQueryFn`.\n */\ntype PersistedODataEntity<TData> = TData extends (infer TItem)[] ? TItem : TData;\ntype PersistedODataRequest<\n\tTMethod extends ODataOperationMethod,\n\tTBody = unknown,\n\tTResponse = TBody,\n\tTEntity = PersistedODataEntity<TResponse>\n> = TMethod extends \"query\"\n\t? ODataFetchFnRequest<\"query\", TEntity, TEntity, TEntity>\n\t: TMethod extends \"create\"\n\t\t? ODataFetchFnRequest<\"create\", TResponse, TResponse, TBody>\n\t\t: TMethod extends \"update\"\n\t\t\t? ODataFetchFnRequest<\"update\", TResponse, TResponse, TBody>\n\t\t\t: TMethod extends \"delete\"\n\t\t\t\t? ODataFetchFnRequest<\"delete\", TResponse, TResponse, TEntity>\n\t\t\t\t: TMethod extends \"read\"\n\t\t\t\t\t? ODataFetchFnRequest<\"read\", TResponse, TResponse, TEntity>\n\t\t\t\t\t: TMethod extends \"fi\"\n\t\t\t\t\t\t? ODataFetchFnRequest<\"fi\", TResponse, TResponse, TEntity>\n\t\t\t\t\t\t: never;\n\n/**\n * Контекст низкоуровневого OData executor.\n */\ninterface PersistedODataExecutorContext {\n\tclient: QueryClient;\n\tsignal?: AbortSignal;\n}\n\n/**\n * Низкоуровневая функция выполнения OData-запроса.\n *\n * По умолчанию используется сам `odataQueryFn`, но в тестах или особых\n * сценариях executor можно подменить.\n */\ntype PersistedODataExecutor<TMethod extends ODataOperationMethod, TBody, TResponse> = (\n\tmethod: TMethod,\n\trequest: PersistedODataRequest<TMethod, TBody, TResponse, PersistedODataEntity<TResponse>>,\n\tcontext: PersistedODataExecutorContext\n) => Promise<{ data: TResponse; totalCount?: number }>;\n\n/**\n * Опции для создания OData query-операции.\n */\ninterface PersistedODataReadOperationOptions<TScope, TArgs, TResponse, TResult> {\n\todata: ODataServiceConfig;\n\tbaseUrl?: BaseURLType;\n\tbuildParams?: (scope: TScope, args: TArgs) => WrappedODataParameters;\n\tbuildOptions?: (scope: TScope, args: TArgs) => ODataFetchOptions<PersistedODataEntity<TResponse>> | undefined;\n\tbuildInit?: (scope: TScope, args: TArgs) => Omit<RequestInit, \"signal\" | \"method\" | \"body\">;\n\ttransform?: (data: TResponse, context: { scope: TScope; args: TArgs }) => TResult;\n\texecutor?: PersistedODataExecutor<\"query\" | \"read\", PersistedODataEntity<TResponse>, TResponse>;\n\tstaleTime?: number;\n\tgcTime?: number;\n\tmeta?: QueryMeta;\n\tisEnabled?: (scope: TScope | null | undefined, args: TArgs) => boolean;\n}\n\n/**\n * Опции для создания OData mutation-операции.\n */\ninterface PersistedODataWriteOperationSharedOptions<TScope, TInput, TResponse, TResult> {\n\todata: ODataServiceConfig;\n\tbaseUrl?: BaseURLType;\n\tbuildOptions?: (scope: TScope, input: TInput) => ODataFetchOptions<PersistedODataEntity<TResponse>> | undefined;\n\tbuildInit?: (scope: TScope, input: TInput) => Omit<RequestInit, \"signal\" | \"method\" | \"body\">;\n\ttransform?: (data: TResponse, context: { scope: TScope; input: TInput }) => TResult;\n\tcacheStrategy?: PersistedMutationOperation<TScope, TInput, TResult>[\"cacheStrategy\"];\n}\n\ntype PersistedODataCreateOperationOptions<TScope, TInput, TBody, TResponse, TResult> = PersistedODataWriteOperationSharedOptions<\n\tTScope,\n\tTInput,\n\tTResponse,\n\tTResult\n> & {\n\tmethod: \"create\";\n\tbuildParams?: never;\n\tbodyMapper: (scope: TScope, input: TInput) => TBody;\n\texecutor?: PersistedODataExecutor<\"create\", TBody, TResponse>;\n};\n\ntype PersistedODataUpdateOperationOptions<TScope, TInput, TBody, TResponse, TResult> = PersistedODataWriteOperationSharedOptions<\n\tTScope,\n\tTInput,\n\tTResponse,\n\tTResult\n> & {\n\tmethod: \"update\";\n\tbuildParams: (scope: TScope, input: TInput) => WrappedODataParameters;\n\tbodyMapper: (scope: TScope, input: TInput) => TBody;\n\texecutor?: PersistedODataExecutor<\"update\", TBody, TResponse>;\n};\n\ntype PersistedODataDeleteOperationOptions<TScope, TInput, TResponse, TResult> = PersistedODataWriteOperationSharedOptions<\n\tTScope,\n\tTInput,\n\tTResponse,\n\tTResult\n> & {\n\tmethod: \"delete\";\n\tbuildParams: (scope: TScope, input: TInput) => WrappedODataParameters;\n\tbodyMapper?: never;\n\texecutor?: PersistedODataExecutor<\"delete\", never, TResponse>;\n};\n\ntype PersistedODataWriteOperationOptions<TScope, TInput, TBody, TResponse, TResult> =\n\t| PersistedODataCreateOperationOptions<TScope, TInput, TBody, TResponse, TResult>\n\t| PersistedODataUpdateOperationOptions<TScope, TInput, TBody, TResponse, TResult>\n\t| PersistedODataDeleteOperationOptions<TScope, TInput, TResponse, TResult>;\n\n/**\n * Выполняет OData-запрос через переданный executor или через дефолтный `odataQueryFn`.\n */\nasync function executePersistedOData<TMethod extends ODataOperationMethod, TBody, TResponse>(\n\tmethod: TMethod,\n\trequest: PersistedODataRequest<TMethod, TBody, TResponse, PersistedODataEntity<TResponse>>,\n\tcontext: PersistedODataExecutorContext,\n\texecutor?: PersistedODataExecutor<TMethod, TBody, TResponse>\n) {\n\tif (executor) {\n\t\treturn await executor(method, request, context);\n\t}\n\n\tswitch (method) {\n\t\tcase \"query\": {\n\t\t\tconst response = await odataFetchFn<PersistedODataEntity<TResponse>, PersistedODataEntity<TResponse>>(\n\t\t\t\t\"query\",\n\t\t\t\trequest as ODataFetchFnRequest<\n\t\t\t\t\t\"query\",\n\t\t\t\t\tPersistedODataEntity<TResponse>,\n\t\t\t\t\tPersistedODataEntity<TResponse>,\n\t\t\t\t\tPersistedODataEntity<TResponse>\n\t\t\t\t> & {\n\t\t\t\t\ttransform?: undefined;\n\t\t\t\t}\n\t\t\t)(context);\n\n\t\t\treturn response as unknown as {\n\t\t\t\tdata: TResponse;\n\t\t\t\ttotalCount?: number;\n\t\t\t};\n\t\t}\n\t\tcase \"create\": {\n\t\t\tconst response = await odataFetchFn<TResponse, TBody, \"create\">(\n\t\t\t\t\"create\",\n\t\t\t\trequest as ODataFetchFnRequest<\"create\", TResponse, TResponse, TBody> & {\n\t\t\t\t\ttransform?: undefined;\n\t\t\t\t}\n\t\t\t)(context);\n\n\t\t\treturn response as unknown as {\n\t\t\t\tdata: TResponse;\n\t\t\t\ttotalCount?: number;\n\t\t\t};\n\t\t}\n\t\tcase \"update\": {\n\t\t\tconst response = await odataFetchFn<TResponse, TBody, \"update\">(\n\t\t\t\t\"update\",\n\t\t\t\trequest as ODataFetchFnRequest<\"update\", TResponse, TResponse, TBody> & {\n\t\t\t\t\ttransform?: undefined;\n\t\t\t\t}\n\t\t\t)(context);\n\n\t\t\treturn response as unknown as {\n\t\t\t\tdata: TResponse;\n\t\t\t\ttotalCount?: number;\n\t\t\t};\n\t\t}\n\t\tcase \"delete\": {\n\t\t\tconst response = await odataFetchFn<TResponse, PersistedODataEntity<TResponse>, \"delete\">(\n\t\t\t\t\"delete\",\n\t\t\t\trequest as ODataFetchFnRequest<\"delete\", TResponse, TResponse, PersistedODataEntity<TResponse>> & {\n\t\t\t\t\ttransform?: undefined;\n\t\t\t\t}\n\t\t\t)(context);\n\n\t\t\treturn response as unknown as {\n\t\t\t\tdata: TResponse;\n\t\t\t\ttotalCount?: number;\n\t\t\t};\n\t\t}\n\t\tcase \"read\": {\n\t\t\tconst response = await odataFetchFn<TResponse, PersistedODataEntity<TResponse>, \"read\">(\n\t\t\t\t\"read\",\n\t\t\t\trequest as ODataFetchFnRequest<\"read\", TResponse, TResponse, PersistedODataEntity<TResponse>> & {\n\t\t\t\t\ttransform?: undefined;\n\t\t\t\t}\n\t\t\t)(context);\n\n\t\t\treturn response as unknown as {\n\t\t\t\tdata: TResponse;\n\t\t\t\ttotalCount?: number;\n\t\t\t};\n\t\t}\n\t\tcase \"fi\": {\n\t\t\tconst response = await odataFetchFn<TResponse, PersistedODataEntity<TResponse>, \"fi\">(\n\t\t\t\t\"fi\",\n\t\t\t\trequest as ODataFetchFnRequest<\"fi\", TResponse, TResponse, PersistedODataEntity<TResponse>> & {\n\t\t\t\t\ttransform?: undefined;\n\t\t\t\t}\n\t\t\t)(context);\n\n\t\t\treturn response as unknown as {\n\t\t\t\tdata: TResponse;\n\t\t\t\ttotalCount?: number;\n\t\t\t};\n\t\t}\n\t}\n}\n\n/**\n * Создаёт query-операцию поверх OData transport.\n *\n * @example\n * ```ts\n * const latestOperation = createPersistedODataQueryOperation({\n * odata: { service: \"TEXT_CONFIG_SRV\", target: \"TEXT_CONFIG_LATEST\" },\n * buildOptions: (scope) => ({\n * expression: buildScopeFilters(scope)\n * }),\n * transform: (rows) => parsePersistedJson(rows[0]?.payload)\n * });\n * ```\n */\nexport function createPersistedODataQueryOperation<TScope, TArgs, TResponse, TResult = TResponse>(\n\toptions: PersistedODataReadOperationOptions<TScope, TArgs, TResponse, TResult>\n): PersistedQueryOperation<TScope, TArgs, TResult> {\n\treturn {\n\t\tisEnabled: options.isEnabled,\n\t\tstaleTime: options.staleTime,\n\t\tgcTime: options.gcTime,\n\t\tmeta: options.meta,\n\t\texecute: async ({ scope, args, client, signal }) => {\n\t\t\tconst response = await executePersistedOData<\"query\", PersistedODataEntity<TResponse>, TResponse>(\n\t\t\t\t\"query\",\n\t\t\t\t{\n\t\t\t\t\todata: options.odata,\n\t\t\t\t\tparams: options.buildParams?.(scope, args),\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\t\t...options.buildOptions?.(scope, args)\n\t\t\t\t\t},\n\t\t\t\t\tinit: options.buildInit?.(scope, args)\n\t\t\t\t} as PersistedODataRequest<\"query\", PersistedODataEntity<TResponse>, TResponse>,\n\t\t\t\t{ client, signal },\n\t\t\t\toptions.executor\n\t\t\t);\n\n\t\t\tif (options.transform) {\n\t\t\t\treturn options.transform(response.data, { scope, args });\n\t\t\t}\n\n\t\t\treturn response.data as unknown as TResult;\n\t\t}\n\t};\n}\n\nexport function createPersistedODataReadOperation<TScope, TArgs, TResponse, TResult = TResponse>(\n\toptions: PersistedODataReadOperationOptions<TScope, TArgs, TResponse, TResult>\n): PersistedQueryOperation<TScope, TArgs, TResult> {\n\treturn {\n\t\tisEnabled: options.isEnabled,\n\t\tstaleTime: options.staleTime,\n\t\tgcTime: options.gcTime,\n\t\tmeta: options.meta,\n\t\texecute: async ({ scope, args, client, signal }) => {\n\t\t\tconst response = await executePersistedOData<\"read\", PersistedODataEntity<TResponse>, TResponse>(\n\t\t\t\t\"read\",\n\t\t\t\t{\n\t\t\t\t\todata: options.odata,\n\t\t\t\t\tparams: options.buildParams?.(scope, args),\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\t\t...options.buildOptions?.(scope, args)\n\t\t\t\t\t},\n\t\t\t\t\tinit: options.buildInit?.(scope, args)\n\t\t\t\t} as PersistedODataRequest<\"read\", PersistedODataEntity<TResponse>, TResponse>,\n\t\t\t\t{ client, signal },\n\t\t\t\toptions.executor\n\t\t\t);\n\n\t\t\tif (options.transform) {\n\t\t\t\treturn options.transform(response.data, { scope, args });\n\t\t\t}\n\n\t\t\treturn response.data as unknown as TResult;\n\t\t}\n\t};\n}\n\n/**\n * Создаёт mutation-операцию поверх OData transport.\n *\n * @example\n * ```ts\n * const saveOperation = createPersistedODataMutationOperation({\n * odata: { service: \"TEXT_CONFIG_SRV\", target: \"TEXT_VARIANT\" },\n * method: \"PUT\",\n * buildParams: (_, input) => ({\n * variantId: { value: input.variantId }\n * }),\n * bodyMapper: (_, input) => input\n * });\n * ```\n */\nexport function createPersistedODataMutationOperation<TScope, TInput, TResponse, TResult = TResponse, TBody = unknown>(\n\toptions: PersistedODataWriteOperationOptions<TScope, TInput, TBody, TResponse, TResult>\n): PersistedMutationOperation<TScope, TInput, TResult> {\n\treturn {\n\t\tcacheStrategy: options.cacheStrategy,\n\t\texecute: async ({ scope, input, client }) => {\n\t\t\tconst response =\n\t\t\t\toptions.method === \"delete\"\n\t\t\t\t\t? await executePersistedOData<\"delete\", never, TResponse>(\n\t\t\t\t\t\t\toptions.method,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\todata: options.odata,\n\t\t\t\t\t\t\t\tparams: options.buildParams(scope, input),\n\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\t\t\t\t\t...options.buildOptions?.(scope, input)\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tinit: options.buildInit?.(scope, input)\n\t\t\t\t\t\t\t} as PersistedODataRequest<\"delete\", never, TResponse, PersistedODataEntity<TResponse>>,\n\t\t\t\t\t\t\t{ client },\n\t\t\t\t\t\t\toptions.executor\n\t\t\t\t\t\t)\n\t\t\t\t\t: options.method === \"update\"\n\t\t\t\t\t\t? await executePersistedOData<\"update\", TBody, TResponse>(\n\t\t\t\t\t\t\t\toptions.method,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\todata: options.odata,\n\t\t\t\t\t\t\t\t\tparams: options.buildParams(scope, input),\n\t\t\t\t\t\t\t\t\tbody: options.bodyMapper(scope, input),\n\t\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\t\t\t\t\t\t...options.buildOptions?.(scope, input)\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tinit: options.buildInit?.(scope, input)\n\t\t\t\t\t\t\t\t} as PersistedODataRequest<\"update\", TBody, TResponse, PersistedODataEntity<TResponse>>,\n\t\t\t\t\t\t\t\t{ client },\n\t\t\t\t\t\t\t\toptions.executor\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: await executePersistedOData<\"create\", TBody, TResponse>(\n\t\t\t\t\t\t\t\toptions.method,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\todata: options.odata,\n\t\t\t\t\t\t\t\t\tbody: options.bodyMapper(scope, input),\n\t\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\t\t\t\t\t\t...options.buildOptions?.(scope, input)\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tinit: options.buildInit?.(scope, input)\n\t\t\t\t\t\t\t\t} as PersistedODataRequest<\"create\", TBody, TResponse, PersistedODataEntity<TResponse>>,\n\t\t\t\t\t\t\t\t{ client },\n\t\t\t\t\t\t\t\toptions.executor\n\t\t\t\t\t\t\t);\n\n\t\t\tif (options.transform) {\n\t\t\t\treturn options.transform(response.data, { scope, input });\n\t\t\t}\n\n\t\t\treturn response.data as unknown as TResult;\n\t\t}\n\t};\n}\n","import type { PersistedPayloadCodec } from \"./types\";\n\n/**\n * Безопасно разбирает JSON payload сохранённой записи.\n *\n * Функция намеренно принимает только строку или `null/undefined`, чтобы нельзя\n * было случайно передать в parser весь record вместо поля `payload`.\n *\n * @example\n * ```ts\n * const payload = parsePersistedJson<{ columns: string[] }>('{\"columns\":[\"A\",\"B\"]}');\n * // => { columns: [\"A\", \"B\"] }\n * ```\n */\nexport function parsePersistedJson<T>(payload: string | null | undefined): T | null {\n\tif (!payload) return null;\n\n\ttry {\n\t\treturn JSON.parse(payload) as T;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Сериализует доменную полезную нагрузку в JSON-строку.\n *\n * @example\n * ```ts\n * const raw = stringifyPersistedJson({ title: \"Demo\" });\n * // => '{\"title\":\"Demo\"}'\n * ```\n */\nexport function stringifyPersistedJson<T>(value: T): string {\n\treturn JSON.stringify(value);\n}\n\n/**\n * Возвращает готовый codec для хранения payload в виде строки JSON.\n */\nexport function createPersistedJsonCodec<T>(): PersistedPayloadCodec<T> {\n\treturn {\n\t\tparse: parsePersistedJson,\n\t\tstringify: stringifyPersistedJson\n\t};\n}\n","import { queryOptions, useMutation, useQuery, useQueryClient, type QueryClient } from \"@tanstack/react-query\";\n\nimport { applyPersistedCacheStrategy } from \"./cache\";\nimport { createPersistedRecordKeys } from \"./keys\";\n\nimport type {\n\tCreatePersistedResourceDescriptorOptions,\n\tPersistedCacheStrategy,\n\tPersistedMutationOperation,\n\tPersistedQueryOperation,\n\tPersistedReadOperationName,\n\tPersistedResourceDescriptor,\n\tPersistedTransportAdapter,\n\tPersistedWriteOperationName\n} from \"./types\";\n\n/**\n * Внутренний тип descriptor-а, гарантированно содержащего нужную read-capability.\n */\ntype ReadDescriptor<TScope, TArgs, TResult, TOperation extends PersistedReadOperationName> = PersistedResourceDescriptor<\n\tTScope,\n\tPersistedTransportAdapter<TScope> & {\n\t\t[K in TOperation]-?: PersistedQueryOperation<TScope, TArgs, TResult>;\n\t}\n>;\n\n/**\n * Внутренний тип descriptor-а, гарантированно содержащего нужную write-capability.\n */\ntype WriteDescriptor<TScope, TInput, TResult, TOperation extends PersistedWriteOperationName> = PersistedResourceDescriptor<\n\tTScope,\n\tPersistedTransportAdapter<TScope> & {\n\t\t[K in TOperation]-?: PersistedMutationOperation<TScope, TInput, TResult>;\n\t}\n>;\n\n/**\n * Дополнительные настройки доменного mutation-хука.\n */\ninterface UsePersistedMutationOptions<TScope, TInput, TResult> {\n\t/**\n\t * Позволяет переопределить стандартную cache policy descriptor-а.\n\t *\n\t * Если передать `null`, базовая strategy ресурса будет отключена.\n\t */\n\tcacheStrategy?: PersistedCacheStrategy<TScope, TInput, TResult> | null;\n\n\t/**\n\t * Доменный post-success callback, который запускается после cache strategy.\n\t */\n\tonSuccess?: (result: TResult, input: TInput) => void | Promise<void>;\n}\n\n/**\n * Проверяет валидность scope и возвращает его в суженном виде.\n */\nfunction assertPersistedScope<TScope, TTransport extends PersistedTransportAdapter<TScope>>(\n\tdescriptor: PersistedResourceDescriptor<TScope, TTransport>,\n\tscope: TScope | null | undefined\n): TScope {\n\tif (scope !== null && scope !== undefined && (descriptor.isEnabled?.(scope) ?? true)) {\n\t\treturn scope;\n\t}\n\n\tthrow new Error(descriptor.getScopeError?.(scope) ?? \"Недостаточно данных scope для persisted-record ресурса.\");\n}\n\n/**\n * Извлекает read-операцию из descriptor-а и даёт раннюю ошибку, если capability\n * не была подключена.\n */\nfunction assertReadOperation<\n\tTScope,\n\tTArgs,\n\tTResult,\n\tTOperation extends PersistedReadOperationName,\n\tTTransport extends PersistedTransportAdapter<TScope>\n>(descriptor: PersistedResourceDescriptor<TScope, TTransport>, operationName: TOperation): PersistedQueryOperation<TScope, TArgs, TResult> {\n\tconst operation = descriptor.transport[operationName];\n\tif (!operation) {\n\t\tthrow new Error(`Persisted-record ресурс '${descriptor.resource}' не поддерживает операцию '${operationName}'.`);\n\t}\n\n\treturn operation as PersistedQueryOperation<TScope, TArgs, TResult>;\n}\n\n/**\n * Извлекает write-операцию из descriptor-а и даёт раннюю ошибку, если capability\n * не была подключена.\n */\nfunction assertWriteOperation<\n\tTScope,\n\tTInput,\n\tTResult,\n\tTOperation extends PersistedWriteOperationName,\n\tTTransport extends PersistedTransportAdapter<TScope>\n>(\n\tdescriptor: PersistedResourceDescriptor<TScope, TTransport>,\n\toperationName: TOperation\n): PersistedMutationOperation<TScope, TInput, TResult> {\n\tconst operation = descriptor.transport[operationName];\n\tif (!operation) {\n\t\tthrow new Error(`Persisted-record ресурс '${descriptor.resource}' не поддерживает операцию '${operationName}'.`);\n\t}\n\n\treturn operation as PersistedMutationOperation<TScope, TInput, TResult>;\n}\n\n/**\n * Строит ключ query/mutation для конкретной операции descriptor-а.\n */\nfunction buildPersistedOperationKey<TScope, TTransport extends PersistedTransportAdapter<TScope>>(\n\tdescriptor: PersistedResourceDescriptor<TScope, TTransport>,\n\toperationName: PersistedReadOperationName | PersistedWriteOperationName,\n\tscope: TScope | null | undefined,\n\targs?: unknown\n) {\n\treturn descriptor.keys.operation(operationName, scope, args);\n}\n\n/**\n * Вычисляет итоговый `enabled` для query.\n *\n * Учитываются:\n * - общая policy descriptor-а;\n * - локальная policy самой операции.\n */\nfunction resolvePersistedQueryEnabled<TScope, TArgs>(\n\tdescriptor: PersistedResourceDescriptor<TScope>,\n\toperation: PersistedQueryOperation<TScope, TArgs, unknown>,\n\tscope: TScope | null | undefined,\n\targs: TArgs\n) {\n\tif (!(descriptor.isEnabled?.(scope) ?? true)) {\n\t\treturn false;\n\t}\n\n\treturn operation.isEnabled?.(scope, args) ?? true;\n}\n\n/**\n * Собирает `queryOptions` для read-операции descriptor-а.\n */\nfunction buildPersistedQueryOptions<TScope, TArgs, TResult, TOperation extends PersistedReadOperationName>(\n\tdescriptor: ReadDescriptor<TScope, TArgs, TResult, TOperation>,\n\toperationName: TOperation,\n\tscope: TScope | null | undefined,\n\targs: TArgs\n) {\n\tconst operation = assertReadOperation(descriptor, operationName) as PersistedQueryOperation<TScope, TArgs, TResult>;\n\tconst enabled = resolvePersistedQueryEnabled(descriptor, operation, scope, args);\n\n\treturn queryOptions({\n\t\tqueryKey: buildPersistedOperationKey(descriptor, operationName, scope, args),\n\t\tqueryFn: ({ client, signal }) => {\n\t\t\tconst resolvedScope = assertPersistedScope(descriptor, scope);\n\t\t\treturn operation.execute({ scope: resolvedScope, args, client, signal });\n\t\t},\n\t\tenabled,\n\t\tstaleTime: operation.staleTime,\n\t\tgcTime: operation.gcTime,\n\t\tmeta: operation.meta\n\t});\n}\n\n/**\n * Общий read-хук для persisted-record операций.\n */\nfunction usePersistedQuery<TScope, TArgs, TResult, TOperation extends PersistedReadOperationName>(\n\tdescriptor: ReadDescriptor<TScope, TArgs, TResult, TOperation>,\n\toperationName: TOperation,\n\tscope: TScope | null | undefined,\n\targs: TArgs\n) {\n\treturn useQuery(buildPersistedQueryOptions(descriptor, operationName, scope, args));\n}\n\n/**\n * Императивный helper для preload/prefetch сценариев через `QueryClient`.\n */\nasync function getPersistedQueryData<TScope, TArgs, TResult, TOperation extends PersistedReadOperationName>(\n\tdescriptor: ReadDescriptor<TScope, TArgs, TResult, TOperation>,\n\toperationName: TOperation,\n\tscope: TScope | null | undefined,\n\targs: TArgs,\n\tqueryClient: QueryClient\n) {\n\treturn await queryClient.fetchQuery(buildPersistedQueryOptions(descriptor, operationName, scope, args));\n}\n\n/**\n * Общий mutation-хук для persisted-record операций.\n *\n * Он выполняет transport-specific мутацию, затем применяет cache strategy и\n * только после этого запускает опциональный доменный `onSuccess`.\n */\nfunction usePersistedMutation<TScope, TInput, TResult, TOperation extends PersistedWriteOperationName>(\n\tdescriptor: WriteDescriptor<TScope, TInput, TResult, TOperation>,\n\toperationName: TOperation,\n\tscope: TScope | null | undefined,\n\toptions?: UsePersistedMutationOptions<TScope, TInput, TResult>\n) {\n\tconst client = useQueryClient();\n\tconst operation = assertWriteOperation(descriptor, operationName) as PersistedMutationOperation<TScope, TInput, TResult>;\n\n\treturn useMutation({\n\t\tmutationKey: buildPersistedOperationKey(descriptor, operationName, scope),\n\t\tmutationFn: async (input: TInput) => {\n\t\t\tconst resolvedScope = assertPersistedScope(descriptor, scope);\n\t\t\treturn await operation.execute({ scope: resolvedScope, input, client });\n\t\t},\n\t\tonSuccess: async (result, input) => {\n\t\t\tconst resolvedScope = assertPersistedScope(descriptor, scope);\n\t\t\tconst cacheStrategy = options?.cacheStrategy === undefined ? operation.cacheStrategy : options.cacheStrategy;\n\n\t\t\tawait applyPersistedCacheStrategy(cacheStrategy, {\n\t\t\t\tclient,\n\t\t\t\tdescriptor,\n\t\t\t\tscope: resolvedScope,\n\t\t\t\tinput,\n\t\t\t\tresult\n\t\t\t});\n\t\t\tawait options?.onSuccess?.(result, input);\n\t\t}\n\t});\n}\n\n/**\n * Создаёт descriptor persisted-record ресурса.\n *\n * @example\n * ```ts\n * const resource = createPersistedResourceDescriptor({\n * namespace: \"viewConfig\",\n * resource: \"view\",\n * normalizeScope: (scope) => ({\n * appId: scope?.appId?.trim() ?? \"\",\n * viewId: scope?.viewId?.trim() ?? \"\"\n * }),\n * isEnabled: (scope) => Boolean(scope?.appId && scope?.viewId),\n * transport: {\n * latest: createPersistedODataQueryOperation({ ... })\n * }\n * });\n * ```\n */\nexport function createPersistedResourceDescriptor<\n\tTScope,\n\tTTransport extends PersistedTransportAdapter<TScope> = PersistedTransportAdapter<TScope>\n>(options: CreatePersistedResourceDescriptorOptions<TScope, TTransport>): PersistedResourceDescriptor<TScope, TTransport> {\n\treturn {\n\t\tnamespace: options.namespace,\n\t\tresource: options.resource,\n\t\tkeys: createPersistedRecordKeys({\n\t\t\tnamespace: options.namespace,\n\t\t\tresource: options.resource,\n\t\t\tnormalizeScope: options.normalizeScope\n\t\t}),\n\t\ttransport: options.transport,\n\t\tisEnabled: options.isEnabled,\n\t\tgetScopeError: options.getScopeError\n\t};\n}\n\n/**\n * Подключает capability `list` к `useQuery`.\n */\nexport function usePersistedListQuery<TScope, TResult>(\n\tdescriptor: ReadDescriptor<TScope, void, TResult, \"list\">,\n\tscope: TScope | null | undefined\n) {\n\treturn usePersistedQuery(descriptor, \"list\", scope, undefined);\n}\n\n/**\n * Подключает capability `latest` к `useQuery`.\n */\nexport function usePersistedLatestQuery<TScope, TResult>(\n\tdescriptor: ReadDescriptor<TScope, void, TResult, \"latest\">,\n\tscope: TScope | null | undefined\n) {\n\treturn usePersistedQuery(descriptor, \"latest\", scope, undefined);\n}\n\n/**\n * Подключает capability `history` к `useQuery`.\n */\nexport function usePersistedHistoryQuery<TScope, TArgs, TResult>(\n\tdescriptor: ReadDescriptor<TScope, TArgs, TResult, \"history\">,\n\tscope: TScope | null | undefined,\n\targs: TArgs\n) {\n\treturn usePersistedQuery(descriptor, \"history\", scope, args);\n}\n\n/**\n * Императивно загружает capability `list` через `QueryClient`.\n */\nexport async function getPersistedListData<TScope, TResult>(\n\tdescriptor: ReadDescriptor<TScope, void, TResult, \"list\">,\n\tscope: TScope | null | undefined,\n\tqueryClient: QueryClient\n) {\n\treturn await getPersistedQueryData(descriptor, \"list\", scope, undefined, queryClient);\n}\n\n/**\n * Императивно загружает capability `latest` через `QueryClient`.\n */\nexport async function getPersistedLatestData<TScope, TResult>(\n\tdescriptor: ReadDescriptor<TScope, void, TResult, \"latest\">,\n\tscope: TScope | null | undefined,\n\tqueryClient: QueryClient\n) {\n\treturn await getPersistedQueryData(descriptor, \"latest\", scope, undefined, queryClient);\n}\n\n/**\n * Императивно загружает capability `history` через `QueryClient`.\n */\nexport async function getPersistedHistoryData<TScope, TArgs, TResult>(\n\tdescriptor: ReadDescriptor<TScope, TArgs, TResult, \"history\">,\n\tscope: TScope | null | undefined,\n\targs: TArgs,\n\tqueryClient: QueryClient\n) {\n\treturn await getPersistedQueryData(descriptor, \"history\", scope, args, queryClient);\n}\n\n/**\n * Подключает capability `save` к `useMutation`.\n */\nexport function usePersistedSaveMutation<TScope, TInput, TResult>(\n\tdescriptor: WriteDescriptor<TScope, TInput, TResult, \"save\">,\n\tscope: TScope | null | undefined,\n\toptions?: UsePersistedMutationOptions<TScope, TInput, TResult>\n) {\n\treturn usePersistedMutation(descriptor, \"save\", scope, options);\n}\n\n/**\n * Подключает capability `create` к `useMutation`.\n */\nexport function usePersistedCreateMutation<TScope, TInput, TResult>(\n\tdescriptor: WriteDescriptor<TScope, TInput, TResult, \"create\">,\n\tscope: TScope | null | undefined,\n\toptions?: UsePersistedMutationOptions<TScope, TInput, TResult>\n) {\n\treturn usePersistedMutation(descriptor, \"create\", scope, options);\n}\n\n/**\n * Подключает capability `delete` к `useMutation`.\n */\nexport function usePersistedDeleteMutation<TScope, TInput, TResult>(\n\tdescriptor: WriteDescriptor<TScope, TInput, TResult, \"delete\">,\n\tscope: TScope | null | undefined,\n\toptions?: UsePersistedMutationOptions<TScope, TInput, TResult>\n) {\n\treturn usePersistedMutation(descriptor, \"delete\", scope, options);\n}\n","import { httpFetchPayload } from \"../http\";\n\nimport type { PersistedMutationOperation, PersistedQueryOperation } from \"./types\";\n\n/**\n * Нормализованная форма REST-запроса, передаваемая executor-у.\n */\ninterface PersistedRestRequest {\n\turl: string;\n\tinit?: RequestInit;\n\tbaseUrl?: string;\n}\n\n/**\n * Низкоуровневый REST executor.\n *\n * Executor можно подменить в тестах и спец-сценариях. Если executor не задан,\n * адаптер использует чистый HTTP transport и требует явный parser ответа.\n */\ntype PersistedRestExecutor<TResponse> = (request: PersistedRestRequest) => Promise<TResponse>;\n\n/**\n * Parser внешнего HTTP payload. REST-слой не приводит `unknown` к доменному типу\n * самостоятельно, чтобы не маскировать контракт endpoint-а.\n */\ntype PersistedRestResponseParser<TResponse> = (payload: unknown) => TResponse;\n\n/**\n * Базовые опции для создания REST read-операции.\n */\ninterface PersistedRestReadOperationBaseOptions<TScope, TArgs, TResponse> {\n\tbaseUrl?: string;\n\tbuildUrl: (scope: TScope, args: TArgs) => string;\n\tbuildInit?: (scope: TScope, args: TArgs) => RequestInit;\n\tparseResponse?: PersistedRestResponseParser<TResponse>;\n\texecutor?: PersistedRestExecutor<TResponse>;\n\tstaleTime?: number;\n\tgcTime?: number;\n\tisEnabled?: (scope: TScope | null | undefined, args: TArgs) => boolean;\n}\n\ntype PersistedRestReadOperationOptions<TScope, TArgs, TResponse> = PersistedRestReadOperationBaseOptions<TScope, TArgs, TResponse>;\n\ntype PersistedRestMappedReadOperationOptions<TScope, TArgs, TResponse, TResult> = PersistedRestReadOperationBaseOptions<\n\tTScope,\n\tTArgs,\n\tTResponse\n> & {\n\ttransform: (data: TResponse, context: { scope: TScope; args: TArgs }) => TResult;\n};\n\n/**\n * Базовые опции для создания REST write-операции.\n */\ninterface PersistedRestWriteOperationBaseOptions<TScope, TInput, TResponse> {\n\tbaseUrl?: string;\n\tbuildUrl: (scope: TScope, input: TInput) => string;\n\tmethod: \"POST\" | \"PUT\" | \"DELETE\";\n\tbuildInit?: (scope: TScope, input: TInput) => Omit<RequestInit, \"method\" | \"body\">;\n\tbodyMapper?: (scope: TScope, input: TInput) => unknown;\n\tparseResponse?: PersistedRestResponseParser<TResponse>;\n\texecutor?: PersistedRestExecutor<TResponse>;\n}\n\ntype PersistedRestWriteOperationOptions<TScope, TInput, TResponse> = PersistedRestWriteOperationBaseOptions<TScope, TInput, TResponse> & {\n\tcacheStrategy?: PersistedMutationOperation<TScope, TInput, TResponse>[\"cacheStrategy\"];\n};\n\ntype PersistedRestMappedWriteOperationOptions<TScope, TInput, TResponse, TResult> = PersistedRestWriteOperationBaseOptions<\n\tTScope,\n\tTInput,\n\tTResponse\n> & {\n\ttransform: (data: TResponse, context: { scope: TScope; input: TInput }) => TResult;\n\tcacheStrategy?: PersistedMutationOperation<TScope, TInput, TResult>[\"cacheStrategy\"];\n};\n\n/**\n * Выполняет REST-запрос через executor или нейтральный HTTP transport.\n */\nasync function executePersistedRest<TResponse>(\n\trequest: PersistedRestRequest,\n\toptions: {\n\t\texecutor?: PersistedRestExecutor<TResponse>;\n\t\tparseResponse?: PersistedRestResponseParser<TResponse>;\n\t}\n) {\n\tif (options.executor) {\n\t\treturn await options.executor(request);\n\t}\n\n\tif (!options.parseResponse) {\n\t\tthrow new Error(\"REST persisted operation requires executor or parseResponse.\");\n\t}\n\n\tconst payload = await httpFetchPayload(request.url, {\n\t\tbaseUrl: request.baseUrl,\n\t\tinit: request.init\n\t});\n\n\treturn options.parseResponse(payload);\n}\n\n/**\n * Создаёт read-операцию поверх обычного REST endpoint.\n */\nexport function createPersistedRestQueryOperation<TScope, TArgs, TResponse>(\n\toptions: PersistedRestReadOperationOptions<TScope, TArgs, TResponse>\n): PersistedQueryOperation<TScope, TArgs, TResponse>;\n\nexport function createPersistedRestQueryOperation<TScope, TArgs, TResponse, TResult>(\n\toptions: PersistedRestMappedReadOperationOptions<TScope, TArgs, TResponse, TResult>\n): PersistedQueryOperation<TScope, TArgs, TResult>;\n\nexport function createPersistedRestQueryOperation<TScope, TArgs, TResponse, TResult>(\n\toptions:\n\t\t| PersistedRestReadOperationOptions<TScope, TArgs, TResponse>\n\t\t| PersistedRestMappedReadOperationOptions<TScope, TArgs, TResponse, TResult>\n): PersistedQueryOperation<TScope, TArgs, TResponse | TResult> {\n\treturn {\n\t\tisEnabled: options.isEnabled,\n\t\tstaleTime: options.staleTime,\n\t\tgcTime: options.gcTime,\n\t\texecute: async ({ scope, args, signal }) => {\n\t\t\tconst data = await executePersistedRest<TResponse>(\n\t\t\t\t{\n\t\t\t\t\turl: options.buildUrl(scope, args),\n\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\tinit: {\n\t\t\t\t\t\t...options.buildInit?.(scope, args),\n\t\t\t\t\t\tsignal\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\texecutor: options.executor,\n\t\t\t\t\tparseResponse: options.parseResponse\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (\"transform\" in options) {\n\t\t\t\treturn options.transform(data, { scope, args });\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\t};\n}\n\n/**\n * Создаёт write-операцию поверх обычного REST endpoint.\n *\n * @example\n * ```ts\n * const savePreset = createPersistedRestMutationOperation({\n * buildUrl: () => \"/api/config-presets\",\n * method: \"PUT\",\n * bodyMapper: (scope, input) => ({\n * userId: scope.userId,\n * payload: input.payload\n * })\n * });\n * ```\n */\nexport function createPersistedRestMutationOperation<TScope, TInput, TResponse>(\n\toptions: PersistedRestWriteOperationOptions<TScope, TInput, TResponse>\n): PersistedMutationOperation<TScope, TInput, TResponse>;\n\nexport function createPersistedRestMutationOperation<TScope, TInput, TResponse, TResult>(\n\toptions: PersistedRestMappedWriteOperationOptions<TScope, TInput, TResponse, TResult>\n): PersistedMutationOperation<TScope, TInput, TResult>;\n\nexport function createPersistedRestMutationOperation<TScope, TInput, TResponse, TResult>(\n\toptions:\n\t\t| PersistedRestWriteOperationOptions<TScope, TInput, TResponse>\n\t\t| PersistedRestMappedWriteOperationOptions<TScope, TInput, TResponse, TResult>\n): PersistedMutationOperation<TScope, TInput, TResponse | TResult> {\n\treturn {\n\t\tcacheStrategy: options.cacheStrategy,\n\t\texecute: async ({ scope, input }) => {\n\t\t\tconst payload = options.bodyMapper?.(scope, input);\n\t\t\tconst data = await executePersistedRest<TResponse>(\n\t\t\t\t{\n\t\t\t\t\turl: options.buildUrl(scope, input),\n\t\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\t\tinit: {\n\t\t\t\t\t\tmethod: options.method,\n\t\t\t\t\t\theaders: payload === undefined ? undefined : { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t...options.buildInit?.(scope, input),\n\t\t\t\t\t\tbody: payload === undefined ? undefined : JSON.stringify(payload)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\texecutor: options.executor,\n\t\t\t\t\tparseResponse: options.parseResponse\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (\"transform\" in options) {\n\t\t\t\treturn options.transform(data, { scope, input });\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\t};\n}\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { PersistedRecordKeys } from "./types";
2
+ /**
3
+ * Создаёт фабрики query key для persisted-record ресурса.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * const keys = createPersistedRecordKeys<{ appId: string; viewId: string }>({
8
+ * namespace: "viewConfig",
9
+ * resource: "view"
10
+ * });
11
+ *
12
+ * keys.latest({ appId: "APP", viewId: "MAIN" });
13
+ * // => ["viewConfig", "view", { appId: "sales", viewId: "CumulativeShipment" }, "latest"]
14
+ * ```
15
+ */
16
+ export declare function createPersistedRecordKeys<TScope>(options: {
17
+ namespace: string;
18
+ resource: string;
19
+ normalizeScope?: (scope: TScope | null | undefined) => unknown;
20
+ }): PersistedRecordKeys<TScope>;
21
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/persisted/keys.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA0B,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE3E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,OAAO,CAAC;CAC/D,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAY9B"}
@@ -0,0 +1,113 @@
1
+ import { type ODataFetchFnRequest, type ODataFetchOptions } from "../odata";
2
+ import { BaseURLType } from "../odata/transport";
3
+ import { PersistedMutationOperation, PersistedQueryOperation } from "./types";
4
+ import type { ODataOperationMethod, ODataServiceConfig, WrappedODataParameters } from "@ryuzaki13/react-foundation-lib/odata-service";
5
+ import type { QueryClient, QueryMeta } from "@tanstack/react-query";
6
+ /**
7
+ * Полная сигнатура конфигурации `odataQueryFn`.
8
+ */
9
+ type PersistedODataEntity<TData> = TData extends (infer TItem)[] ? TItem : TData;
10
+ type PersistedODataRequest<TMethod extends ODataOperationMethod, TBody = unknown, TResponse = TBody, TEntity = PersistedODataEntity<TResponse>> = TMethod extends "query" ? ODataFetchFnRequest<"query", TEntity, TEntity, TEntity> : TMethod extends "create" ? ODataFetchFnRequest<"create", TResponse, TResponse, TBody> : TMethod extends "update" ? ODataFetchFnRequest<"update", TResponse, TResponse, TBody> : TMethod extends "delete" ? ODataFetchFnRequest<"delete", TResponse, TResponse, TEntity> : TMethod extends "read" ? ODataFetchFnRequest<"read", TResponse, TResponse, TEntity> : TMethod extends "fi" ? ODataFetchFnRequest<"fi", TResponse, TResponse, TEntity> : never;
11
+ /**
12
+ * Контекст низкоуровневого OData executor.
13
+ */
14
+ interface PersistedODataExecutorContext {
15
+ client: QueryClient;
16
+ signal?: AbortSignal;
17
+ }
18
+ /**
19
+ * Низкоуровневая функция выполнения OData-запроса.
20
+ *
21
+ * По умолчанию используется сам `odataQueryFn`, но в тестах или особых
22
+ * сценариях executor можно подменить.
23
+ */
24
+ type PersistedODataExecutor<TMethod extends ODataOperationMethod, TBody, TResponse> = (method: TMethod, request: PersistedODataRequest<TMethod, TBody, TResponse, PersistedODataEntity<TResponse>>, context: PersistedODataExecutorContext) => Promise<{
25
+ data: TResponse;
26
+ totalCount?: number;
27
+ }>;
28
+ /**
29
+ * Опции для создания OData query-операции.
30
+ */
31
+ interface PersistedODataReadOperationOptions<TScope, TArgs, TResponse, TResult> {
32
+ odata: ODataServiceConfig;
33
+ baseUrl?: BaseURLType;
34
+ buildParams?: (scope: TScope, args: TArgs) => WrappedODataParameters;
35
+ buildOptions?: (scope: TScope, args: TArgs) => ODataFetchOptions<PersistedODataEntity<TResponse>> | undefined;
36
+ buildInit?: (scope: TScope, args: TArgs) => Omit<RequestInit, "signal" | "method" | "body">;
37
+ transform?: (data: TResponse, context: {
38
+ scope: TScope;
39
+ args: TArgs;
40
+ }) => TResult;
41
+ executor?: PersistedODataExecutor<"query" | "read", PersistedODataEntity<TResponse>, TResponse>;
42
+ staleTime?: number;
43
+ gcTime?: number;
44
+ meta?: QueryMeta;
45
+ isEnabled?: (scope: TScope | null | undefined, args: TArgs) => boolean;
46
+ }
47
+ /**
48
+ * Опции для создания OData mutation-операции.
49
+ */
50
+ interface PersistedODataWriteOperationSharedOptions<TScope, TInput, TResponse, TResult> {
51
+ odata: ODataServiceConfig;
52
+ baseUrl?: BaseURLType;
53
+ buildOptions?: (scope: TScope, input: TInput) => ODataFetchOptions<PersistedODataEntity<TResponse>> | undefined;
54
+ buildInit?: (scope: TScope, input: TInput) => Omit<RequestInit, "signal" | "method" | "body">;
55
+ transform?: (data: TResponse, context: {
56
+ scope: TScope;
57
+ input: TInput;
58
+ }) => TResult;
59
+ cacheStrategy?: PersistedMutationOperation<TScope, TInput, TResult>["cacheStrategy"];
60
+ }
61
+ type PersistedODataCreateOperationOptions<TScope, TInput, TBody, TResponse, TResult> = PersistedODataWriteOperationSharedOptions<TScope, TInput, TResponse, TResult> & {
62
+ method: "create";
63
+ buildParams?: never;
64
+ bodyMapper: (scope: TScope, input: TInput) => TBody;
65
+ executor?: PersistedODataExecutor<"create", TBody, TResponse>;
66
+ };
67
+ type PersistedODataUpdateOperationOptions<TScope, TInput, TBody, TResponse, TResult> = PersistedODataWriteOperationSharedOptions<TScope, TInput, TResponse, TResult> & {
68
+ method: "update";
69
+ buildParams: (scope: TScope, input: TInput) => WrappedODataParameters;
70
+ bodyMapper: (scope: TScope, input: TInput) => TBody;
71
+ executor?: PersistedODataExecutor<"update", TBody, TResponse>;
72
+ };
73
+ type PersistedODataDeleteOperationOptions<TScope, TInput, TResponse, TResult> = PersistedODataWriteOperationSharedOptions<TScope, TInput, TResponse, TResult> & {
74
+ method: "delete";
75
+ buildParams: (scope: TScope, input: TInput) => WrappedODataParameters;
76
+ bodyMapper?: never;
77
+ executor?: PersistedODataExecutor<"delete", never, TResponse>;
78
+ };
79
+ type PersistedODataWriteOperationOptions<TScope, TInput, TBody, TResponse, TResult> = PersistedODataCreateOperationOptions<TScope, TInput, TBody, TResponse, TResult> | PersistedODataUpdateOperationOptions<TScope, TInput, TBody, TResponse, TResult> | PersistedODataDeleteOperationOptions<TScope, TInput, TResponse, TResult>;
80
+ /**
81
+ * Создаёт query-операцию поверх OData transport.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const latestOperation = createPersistedODataQueryOperation({
86
+ * odata: { service: "TEXT_CONFIG_SRV", target: "TEXT_CONFIG_LATEST" },
87
+ * buildOptions: (scope) => ({
88
+ * expression: buildScopeFilters(scope)
89
+ * }),
90
+ * transform: (rows) => parsePersistedJson(rows[0]?.payload)
91
+ * });
92
+ * ```
93
+ */
94
+ export declare function createPersistedODataQueryOperation<TScope, TArgs, TResponse, TResult = TResponse>(options: PersistedODataReadOperationOptions<TScope, TArgs, TResponse, TResult>): PersistedQueryOperation<TScope, TArgs, TResult>;
95
+ export declare function createPersistedODataReadOperation<TScope, TArgs, TResponse, TResult = TResponse>(options: PersistedODataReadOperationOptions<TScope, TArgs, TResponse, TResult>): PersistedQueryOperation<TScope, TArgs, TResult>;
96
+ /**
97
+ * Создаёт mutation-операцию поверх OData transport.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * const saveOperation = createPersistedODataMutationOperation({
102
+ * odata: { service: "TEXT_CONFIG_SRV", target: "TEXT_VARIANT" },
103
+ * method: "PUT",
104
+ * buildParams: (_, input) => ({
105
+ * variantId: { value: input.variantId }
106
+ * }),
107
+ * bodyMapper: (_, input) => input
108
+ * });
109
+ * ```
110
+ */
111
+ export declare function createPersistedODataMutationOperation<TScope, TInput, TResponse, TResult = TResponse, TBody = unknown>(options: PersistedODataWriteOperationOptions<TScope, TInput, TBody, TResponse, TResult>): PersistedMutationOperation<TScope, TInput, TResult>;
112
+ export {};
113
+ //# sourceMappingURL=odata.d.ts.map