@mgarlik/datastore 0.1.27 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -735,7 +735,14 @@ var getData = async ({ id, dataSource, isPersisting, schema, SQLite, changeTime
735
735
  }).filter((item) => item !== null);
736
736
  }
737
737
  if (dataSource) {
738
- const axiosResponse = await import_axios.default.get(buildUri({ dataSource, method: "read" }), { params: serializeParams(params) });
738
+ const serializedParams = serializeParams(params);
739
+ console.log("[HANDLE DATA] outgoing read params", buildUri({ dataSource, method: "read" }), serializedParams);
740
+ console.assert(
741
+ !(typeof serializedParams.filter === "string" && serializedParams.filter.includes('"$source"')),
742
+ "[HANDLE DATA] unresolved $source reached outgoing filter",
743
+ serializedParams.filter
744
+ );
745
+ const axiosResponse = await import_axios.default.get(buildUri({ dataSource, method: "read" }), { params: serializedParams });
739
746
  if (schema && !dataSource.readAllFields) {
740
747
  const mapBySchema = (element) => {
741
748
  const mappedRow = {};
@@ -820,9 +827,8 @@ var deleteData = async ({ dataSource, data }) => {
820
827
  }
821
828
  };
822
829
 
823
- // src/DataStoreProvider.tsx
824
- var import_socket = require("socket.io-client");
825
- var import_axios2 = __toESM(require("axios"), 1);
830
+ // src/sourceResolution.ts
831
+ var import_json_filter = require("@mgarlik/json-filter");
826
832
 
827
833
  // src/templates.ts
828
834
  var _renderMyTemplate = (templateString, data) => {
@@ -851,7 +857,84 @@ function renderJSONTemplate(val, data) {
851
857
  return parsedObj;
852
858
  }
853
859
 
860
+ // src/sourceResolution.ts
861
+ var resolveProviderRef = (providerId, providers, presetProviders, params) => {
862
+ if (providers[providerId]) {
863
+ return { templateId: providerId, runtimeId: providerId };
864
+ }
865
+ if (presetProviders[providerId]) {
866
+ const renderedProvider = renderJSONTemplate(presetProviders[providerId], params ?? void 0);
867
+ return { templateId: providerId, runtimeId: renderedProvider.id };
868
+ }
869
+ return null;
870
+ };
871
+ var collectObjectSourceProviders = (obj, result) => {
872
+ if (!obj || typeof obj !== "object") return;
873
+ if (Array.isArray(obj)) {
874
+ obj.forEach((item) => collectObjectSourceProviders(item, result));
875
+ return;
876
+ }
877
+ if (obj.$source?.dataProvider) {
878
+ result.add(String(obj.$source.dataProvider));
879
+ }
880
+ if (obj.dataSource?.dataProvider) {
881
+ result.add(String(obj.dataSource.dataProvider));
882
+ }
883
+ Object.values(obj).forEach((value) => collectObjectSourceProviders(value, result));
884
+ };
885
+ var collectSourceProviders = (value) => {
886
+ const result = /* @__PURE__ */ new Set();
887
+ collectObjectSourceProviders(value, result);
888
+ return Array.from(result);
889
+ };
890
+ var resolveDynamicValue = (value, context, stack = []) => {
891
+ if (value === null || value === void 0) return value;
892
+ if (Array.isArray(value)) {
893
+ return value.map((item) => resolveDynamicValue(item, context, stack));
894
+ }
895
+ if (typeof value !== "object") return value;
896
+ const sourceKeys = Object.keys(value);
897
+ if (sourceKeys.length === 1 && sourceKeys[0] === "$source") {
898
+ return resolveSourceConfig(value.$source, context, stack);
899
+ }
900
+ const result = {};
901
+ for (const [key, item] of Object.entries(value)) {
902
+ result[key] = resolveDynamicValue(item, context, stack);
903
+ }
904
+ return result;
905
+ };
906
+ var resolveSourceConfig = (source, context, stack = []) => {
907
+ if (!source?.dataProvider) return source?.val ? null : void 0;
908
+ const resolvedRef = resolveProviderRef(source.dataProvider, context.providers, context.presetProviders, context.params);
909
+ if (!resolvedRef) return source.val ? null : void 0;
910
+ if (stack.includes(resolvedRef.runtimeId)) {
911
+ throw new Error(`Cyclic $source reference detected for provider ${resolvedRef.runtimeId}`);
912
+ }
913
+ const provider = context.providers[resolvedRef.runtimeId];
914
+ if (!provider) return source.map ? [] : source.val ? null : void 0;
915
+ const providerDocuments = Array.isArray(provider.data) ? provider.data.map((docId) => {
916
+ const doc = context.documents[docId];
917
+ if (!doc) return null;
918
+ return { id: docId, ...doc };
919
+ }).filter((item) => item !== null) : [];
920
+ const resolvedFilter = source.filter ? resolveDynamicValue(source.filter, context, [...stack, resolvedRef.runtimeId]) : void 0;
921
+ const filteredDocuments = resolvedFilter ? (0, import_json_filter.filterJsonDocuments)(providerDocuments, resolvedFilter) : providerDocuments;
922
+ if (source.map) {
923
+ return filteredDocuments.map((item) => getValueByDotPath(item, source.map)).filter((item) => item !== void 0);
924
+ }
925
+ if (source.val) {
926
+ if (filteredDocuments.length === 0) return null;
927
+ if (filteredDocuments.length > 1) {
928
+ throw new Error(`$source.val expects exactly one document from ${source.dataProvider}, got ${filteredDocuments.length}`);
929
+ }
930
+ return getValueByDotPath(filteredDocuments[0], source.val) ?? null;
931
+ }
932
+ return filteredDocuments;
933
+ };
934
+
854
935
  // src/DataStoreProvider.tsx
936
+ var import_socket = require("socket.io-client");
937
+ var import_axios2 = __toESM(require("axios"), 1);
855
938
  var import_isEqual = __toESM(require("lodash/isEqual.js"), 1);
856
939
  var import_jsx_runtime = require("react/jsx-runtime");
857
940
  var DataStoreContext = (0, import_react.createContext)({});
@@ -886,11 +969,13 @@ var useDocuments = () => {
886
969
  var useProviderDocuments = (provider, settings) => {
887
970
  const documents = (0, import_react.useContext)(DataStoreDocumentsContext);
888
971
  const providers = (0, import_react.useContext)(DataStoreProvidersContext);
972
+ const presetProviders = (0, import_react.useContext)(DataStoreStableContext).presetProviders;
973
+ const resolvedFilter = settings?.filter ? resolveDynamicValue(settings.filter, { providers, documents, presetProviders }) : void 0;
889
974
  const docs = (0, import_react.useMemo)(() => {
890
975
  console.log("useProviderDocuments", provider);
891
976
  const d = {};
892
977
  providers[provider]?.data.forEach((id) => {
893
- if (settings?.filter && !doesObjectMatchFilter(documents[id], settings.filter)) return;
978
+ if (resolvedFilter && !doesObjectMatchFilter(documents[id], resolvedFilter)) return;
894
979
  let result = documents[id];
895
980
  if (providers[provider].depend) {
896
981
  result = recalculateObjectWithDocument(documents[id], documents[providers[provider].depend]);
@@ -902,7 +987,16 @@ var useProviderDocuments = (provider, settings) => {
902
987
  d[id] = result;
903
988
  });
904
989
  return d;
905
- }, [providers[provider]?.lastUpdate, documents[providers[provider]?.depend], settings?.filter, settings?.documentId, settings?.document]);
990
+ }, [
991
+ providers[provider]?.lastUpdate,
992
+ documents[providers[provider]?.depend],
993
+ settings?.filter,
994
+ settings?.documentId,
995
+ settings?.document,
996
+ providers,
997
+ documents,
998
+ presetProviders
999
+ ]);
906
1000
  return { documents: docs };
907
1001
  };
908
1002
  var useProvider = (val) => {
@@ -962,6 +1056,8 @@ var DataStoreProvider = (0, import_react.forwardRef)(
962
1056
  const [counterProviders, setCounterProviders] = (0, import_react.useState)({});
963
1057
  const [counterDocuments, setCounterDocuments] = (0, import_react.useState)({});
964
1058
  const didInitialLiveSyncRef = (0, import_react.useRef)(false);
1059
+ const providerDynamicSourceStateRef = (0, import_react.useRef)({});
1060
+ const providerDynamicRefreshInProgressRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
965
1061
  const persistenceStorage = (0, import_react.useMemo)(
966
1062
  () => usePersistentStorage ? storage : null,
967
1063
  [storage, usePersistentStorage]
@@ -1077,6 +1173,7 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1077
1173
  const response = await getData({
1078
1174
  id: key,
1079
1175
  ...rest,
1176
+ dataSource: resolveDynamicValue(rest.dataSource || {}, { providers, documents, presetProviders }),
1080
1177
  changeTime: lastUpdate.time
1081
1178
  });
1082
1179
  if (response.length > 0) {
@@ -1361,7 +1458,10 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1361
1458
  if (dP) {
1362
1459
  const dataFromSource = await getData({
1363
1460
  id: dP.id,
1364
- dataSource: { ...dP.dataSource, params: { select: fields.join(" ") } },
1461
+ dataSource: resolveDynamicValue(
1462
+ { ...dP.dataSource, params: { select: fields.join(" ") } },
1463
+ { providers, documents, presetProviders }
1464
+ ),
1365
1465
  isPersisting: !!dP.isPersisting && !!persistenceStorage,
1366
1466
  schema: dP.schema,
1367
1467
  SQLite: persistenceStorage || void 0
@@ -1384,9 +1484,10 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1384
1484
  data: Array.isArray(provider?.data) ? [...provider.data] : []
1385
1485
  };
1386
1486
  var socketListeners = providerNext.dataSource?.socketListeners || [];
1487
+ const resolvedProviderFilter = providerNext.dataSource?.filter ? resolveDynamicValue(providerNext.dataSource.filter, { providers, documents, presetProviders }) : void 0;
1387
1488
  if (socketListeners.length === 0) {
1388
1489
  if (providerNext.data.includes(documentId)) {
1389
- if (!providerNext.dataSource?.filter || filterDocuments(documentForFilter, providerNext.dataSource?.filter)) {
1490
+ if (!resolvedProviderFilter || filterDocuments(documentForFilter, resolvedProviderFilter)) {
1390
1491
  listeningProviders++;
1391
1492
  providerNext.lastUpdate = {
1392
1493
  id: uuid(),
@@ -1405,7 +1506,7 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1405
1506
  }
1406
1507
  } else if (socketListeners.includes(model) || // socketListeners.includes(documentId) ||
1407
1508
  key === model) {
1408
- if (!providerNext.dataSource.filter || filterDocuments(documentForFilter, providerNext.dataSource.filter)) {
1509
+ if (!resolvedProviderFilter || filterDocuments(documentForFilter, resolvedProviderFilter)) {
1409
1510
  listeningProviders++;
1410
1511
  providerNext.lastUpdate = {
1411
1512
  id: uuid(),
@@ -1524,7 +1625,8 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1524
1625
  Object.keys(providers).forEach((key) => {
1525
1626
  const provider = providers[key];
1526
1627
  var socketListeners = provider.dataSource?.socketListeners;
1527
- if ((socketListeners?.includes(model) || key === model) && (!provider.dataSource?.filter || filterDocuments(newDocument, provider.dataSource?.filter))) {
1628
+ const resolvedProviderFilter = provider.dataSource?.filter ? resolveDynamicValue(provider.dataSource.filter, { providers, documents, presetProviders }) : void 0;
1629
+ if ((socketListeners?.includes(model) || key === model) && (!resolvedProviderFilter || filterDocuments(newDocument, resolvedProviderFilter))) {
1528
1630
  if (!provider.data.includes(documentId)) {
1529
1631
  setCounterDocuments((prev) => {
1530
1632
  const newC = { ...prev };
@@ -1687,6 +1789,171 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1687
1789
  },
1688
1790
  [setSockets, socket]
1689
1791
  );
1792
+ const buildResolvedDataSourceSnapshot = (0, import_react.useCallback)(
1793
+ (providerId) => {
1794
+ const provider = providers[providerId];
1795
+ if (!provider?.dataSource) return null;
1796
+ const dependencies = collectSourceProviders(provider.dataSource);
1797
+ if (dependencies.length === 0) return null;
1798
+ const resolvedDataSource = resolveDynamicValue(provider.dataSource, { providers, documents, presetProviders });
1799
+ return {
1800
+ resolvedDataSource,
1801
+ signature: JSON.stringify(resolvedDataSource ?? {}),
1802
+ socketFilter: resolvedDataSource?.filter ?? {}
1803
+ };
1804
+ },
1805
+ [providers, documents, presetProviders]
1806
+ );
1807
+ const refreshProviderFromResolvedDataSource = (0, import_react.useCallback)(
1808
+ async (providerId, resolvedDataSource, resolvedSocketFilter) => {
1809
+ const provider = providers[providerId];
1810
+ if (!provider) return;
1811
+ console.log("[DSP][dynamic] reload start", {
1812
+ providerId,
1813
+ previousCount: Array.isArray(provider.data) ? provider.data.length : 0
1814
+ });
1815
+ const dataFromSource = await getData({
1816
+ schema: provider.schema,
1817
+ dataSource: resolvedDataSource,
1818
+ id: providerId,
1819
+ isPersisting: !!provider.isPersisting && !!persistenceStorage,
1820
+ SQLite: persistenceStorage || void 0
1821
+ });
1822
+ const nextDocumentIds = [];
1823
+ const nextDocuments = {};
1824
+ const sourceItems = Array.isArray(dataFromSource) ? dataFromSource : [dataFromSource];
1825
+ sourceItems.forEach((item) => {
1826
+ if (!item || typeof item !== "object") return;
1827
+ const { id, ...data } = item;
1828
+ const normalizedId = id || uuid();
1829
+ nextDocumentIds.push(normalizedId);
1830
+ nextDocuments[normalizedId] = documents[normalizedId] ? { ...documents[normalizedId], ...data } : data;
1831
+ });
1832
+ const previousDocumentIds = Array.isArray(provider.data) ? provider.data : [];
1833
+ const previousSet = new Set(previousDocumentIds);
1834
+ const nextSet = new Set(nextDocumentIds);
1835
+ const addedDocumentIds = nextDocumentIds.filter((itemId) => !previousSet.has(itemId));
1836
+ const removedDocumentIds = previousDocumentIds.filter((itemId) => !nextSet.has(itemId));
1837
+ setCounterDocuments((prev) => {
1838
+ const nextCounters = { ...prev };
1839
+ const documentsToDelete = [];
1840
+ removedDocumentIds.forEach((itemId) => {
1841
+ if (!nextCounters[itemId] || nextCounters[itemId] <= 1) {
1842
+ delete nextCounters[itemId];
1843
+ documentsToDelete.push(itemId);
1844
+ } else {
1845
+ nextCounters[itemId] = nextCounters[itemId] - 1;
1846
+ }
1847
+ });
1848
+ addedDocumentIds.forEach((itemId) => {
1849
+ nextCounters[itemId] = (nextCounters[itemId] || 0) + 1;
1850
+ });
1851
+ setDocuments((prevDocs) => {
1852
+ const nextDocs = { ...prevDocs };
1853
+ documentsToDelete.forEach((itemId) => {
1854
+ delete nextDocs[itemId];
1855
+ });
1856
+ Object.entries(nextDocuments).forEach(([itemId, itemData]) => {
1857
+ nextDocs[itemId] = itemData;
1858
+ });
1859
+ return nextDocs;
1860
+ });
1861
+ return nextCounters;
1862
+ });
1863
+ setProviders((prev) => {
1864
+ if (!prev[providerId]) return prev;
1865
+ return {
1866
+ ...prev,
1867
+ [providerId]: {
1868
+ ...prev[providerId],
1869
+ data: nextDocumentIds,
1870
+ _resolvedSocketFilter: resolvedSocketFilter,
1871
+ lastUpdate: { id: uuid(), time: /* @__PURE__ */ new Date() }
1872
+ }
1873
+ };
1874
+ });
1875
+ console.log("[DSP][dynamic] reload done", {
1876
+ providerId,
1877
+ nextCount: nextDocumentIds.length,
1878
+ added: addedDocumentIds.length,
1879
+ removed: removedDocumentIds.length,
1880
+ socketFilter: resolvedSocketFilter
1881
+ });
1882
+ if (provider?.isPersisting && persistenceStorage) {
1883
+ await Promise.all(removedDocumentIds.map((itemId) => removePersistedDocument(itemId)));
1884
+ await Promise.all(
1885
+ Object.entries(nextDocuments).map(
1886
+ ([itemId, itemData]) => persistDocument({ documentId: itemId, model: providerId, data: itemData })
1887
+ )
1888
+ );
1889
+ }
1890
+ },
1891
+ [providers, documents, persistenceStorage, removePersistedDocument, persistDocument]
1892
+ );
1893
+ (0, import_react.useEffect)(() => {
1894
+ const trackedProviderIds = Object.keys(providers).filter((providerId) => {
1895
+ const provider = providers[providerId];
1896
+ return !!provider?.dataSource && collectSourceProviders(provider.dataSource).length > 0;
1897
+ });
1898
+ const trackedSet = new Set(trackedProviderIds);
1899
+ Object.keys(providerDynamicSourceStateRef.current).forEach((providerId) => {
1900
+ if (!trackedSet.has(providerId)) {
1901
+ delete providerDynamicSourceStateRef.current[providerId];
1902
+ }
1903
+ });
1904
+ trackedProviderIds.forEach((providerId) => {
1905
+ const snapshot = buildResolvedDataSourceSnapshot(providerId);
1906
+ if (!snapshot) return;
1907
+ const previousSnapshot = providerDynamicSourceStateRef.current[providerId];
1908
+ if (!previousSnapshot) {
1909
+ providerDynamicSourceStateRef.current[providerId] = {
1910
+ signature: snapshot.signature,
1911
+ socketFilter: snapshot.socketFilter
1912
+ };
1913
+ return;
1914
+ }
1915
+ if (previousSnapshot.signature === snapshot.signature) return;
1916
+ if (providerDynamicRefreshInProgressRef.current.has(providerId)) return;
1917
+ console.log("[DSP][dynamic] dataSource changed", {
1918
+ providerId,
1919
+ previousFilter: previousSnapshot.socketFilter,
1920
+ nextFilter: snapshot.socketFilter
1921
+ });
1922
+ providerDynamicSourceStateRef.current[providerId] = {
1923
+ signature: snapshot.signature,
1924
+ socketFilter: snapshot.socketFilter
1925
+ };
1926
+ providerDynamicRefreshInProgressRef.current.add(providerId);
1927
+ const provider = providers[providerId];
1928
+ const socketListeners = provider?.dataSource?.socketListeners;
1929
+ (async () => {
1930
+ try {
1931
+ if (socketListeners && !(0, import_isEqual.default)(previousSnapshot.socketFilter, snapshot.socketFilter)) {
1932
+ console.log("[DSP][dynamic] socket filter refresh", {
1933
+ providerId,
1934
+ socketListeners,
1935
+ previousFilter: previousSnapshot.socketFilter,
1936
+ nextFilter: snapshot.socketFilter
1937
+ });
1938
+ unregisterProviderSockets(socketListeners, previousSnapshot.socketFilter);
1939
+ registerProviderSockets(socketListeners, snapshot.socketFilter);
1940
+ }
1941
+ await refreshProviderFromResolvedDataSource(providerId, snapshot.resolvedDataSource, snapshot.socketFilter);
1942
+ } catch (error) {
1943
+ console.error("[DataStoreProvider] dynamic dataSource refresh error", { providerId, error });
1944
+ } finally {
1945
+ providerDynamicRefreshInProgressRef.current.delete(providerId);
1946
+ }
1947
+ })();
1948
+ });
1949
+ }, [
1950
+ providers,
1951
+ documents,
1952
+ buildResolvedDataSourceSnapshot,
1953
+ refreshProviderFromResolvedDataSource,
1954
+ registerProviderSockets,
1955
+ unregisterProviderSockets
1956
+ ]);
1690
1957
  const updateProviderListeners = (0, import_react.useCallback)(
1691
1958
  async (id, val) => {
1692
1959
  setCounterProviders((prev) => {
@@ -1699,7 +1966,7 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1699
1966
  const newS = { ...prevS };
1700
1967
  const removeSocketListeners = [];
1701
1968
  const providerSocketListeners = prevP[id].dataSource?.socketListeners || [];
1702
- const providerFilter = prevP[id].dataSource?.filter;
1969
+ const providerFilter = prevP[id]._resolvedSocketFilter ?? prevP[id].dataSource?.filter;
1703
1970
  const normalizedFilter = providerFilter ?? {};
1704
1971
  providerSocketListeners.forEach((socketName) => {
1705
1972
  if (!newS[socketName]) return;
@@ -1763,9 +2030,10 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1763
2030
  result = providers[id];
1764
2031
  } else {
1765
2032
  try {
2033
+ const resolvedDataSource = resolveDynamicValue(newItem.dataSource || {}, { providers, documents, presetProviders });
1766
2034
  const dataFromSource = await getData({
1767
2035
  schema: newItem.schema,
1768
- dataSource: newItem.dataSource || {},
2036
+ dataSource: resolvedDataSource,
1769
2037
  id: newItem.id,
1770
2038
  isPersisting: !!newItem.isPersisting && !!persistenceStorage,
1771
2039
  SQLite: persistenceStorage || void 0
@@ -1804,6 +2072,7 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1804
2072
  result = {
1805
2073
  ...provider,
1806
2074
  data: dataList,
2075
+ _resolvedSocketFilter: resolvedDataSource?.filter ?? {},
1807
2076
  lastUpdate: { id: uuid(), time: /* @__PURE__ */ new Date() }
1808
2077
  };
1809
2078
  setProviders((prev) => ({
@@ -1816,7 +2085,7 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1816
2085
  }));
1817
2086
  if (provider.dataSource?.socketListeners) {
1818
2087
  console.log("TATATATA");
1819
- registerProviderSockets(provider.dataSource.socketListeners, provider.dataSource.filter);
2088
+ registerProviderSockets(provider.dataSource.socketListeners, resolvedDataSource?.filter ?? {});
1820
2089
  }
1821
2090
  } catch (error) {
1822
2091
  console.error("[DataStoreProvider] registerProvider:error", { id: newItem.id, error });
@@ -1837,7 +2106,10 @@ var DataStoreProvider = (0, import_react.forwardRef)(
1837
2106
  [itemId]: prev[itemId] - 1
1838
2107
  };
1839
2108
  } else {
1840
- unregisterProviderSockets(providers[itemId]?.dataSource.socketListeners, providers[itemId]?.dataSource.filter);
2109
+ unregisterProviderSockets(
2110
+ providers[itemId]?.dataSource.socketListeners,
2111
+ providers[itemId]?._resolvedSocketFilter ?? providers[itemId]?.dataSource.filter
2112
+ );
1841
2113
  setCounterDocuments((cd) => {
1842
2114
  const newC = { ...cd };
1843
2115
  const deleteDocumentIds = [];
@@ -1939,14 +2211,15 @@ var DataStoreProvider_default = DataStoreProvider;
1939
2211
 
1940
2212
  // src/useDataProvider.tsx
1941
2213
  var import_react2 = require("react");
1942
- var import_json_filter = require("@mgarlik/json-filter");
2214
+ var import_json_filter2 = require("@mgarlik/json-filter");
1943
2215
  var findAllDataProviders = (obj) => {
1944
2216
  if (!obj || typeof obj !== "object") return [];
1945
2217
  if (obj.dataSource?.dataProvider) return [obj.dataSource.dataProvider];
2218
+ if (obj.$source?.dataProvider) return [obj.$source.dataProvider];
1946
2219
  if (Array.isArray(obj)) return obj.flatMap(findAllDataProviders);
1947
2220
  return Object.values(obj).flatMap(findAllDataProviders);
1948
2221
  };
1949
- var resolveProviderRef = (providerId, providers, presetProviders, params) => {
2222
+ var resolveProviderRef2 = (providerId, providers, presetProviders, params) => {
1950
2223
  if (providers[providerId]) {
1951
2224
  return { templateId: providerId, runtimeId: providerId };
1952
2225
  }
@@ -1977,7 +2250,7 @@ var createOptionFromDocument = (doc, map) => {
1977
2250
  var resolveDataSourcesDeep = (obj, providers, documents, presetProviders, params, logLabel = "options") => {
1978
2251
  if (!obj || typeof obj !== "object") return obj;
1979
2252
  if (obj.dataSource?.dataProvider) {
1980
- const providerRef = resolveProviderRef(obj.dataSource.dataProvider, providers, presetProviders, params);
2253
+ const providerRef = resolveProviderRef2(obj.dataSource.dataProvider, providers, presetProviders, params);
1981
2254
  const optionProvider = providers[providerRef.runtimeId];
1982
2255
  if (!optionProvider) {
1983
2256
  systemLog("usedp", `Nenalezen provider pro ${logLabel}`, obj.dataSource.dataProvider);
@@ -1989,7 +2262,8 @@ var resolveDataSourcesDeep = (obj, providers, documents, presetProviders, params
1989
2262
  return { id: docId, ...docData };
1990
2263
  }).filter((item) => !!item);
1991
2264
  if (obj.dataSource.filter) {
1992
- optionDocuments = (0, import_json_filter.filterJsonDocuments)(optionDocuments, obj.dataSource.filter);
2265
+ const resolvedFilter = resolveDynamicValue(obj.dataSource.filter, { providers, documents, presetProviders, params });
2266
+ optionDocuments = (0, import_json_filter2.filterJsonDocuments)(optionDocuments, resolvedFilter);
1993
2267
  }
1994
2268
  return optionDocuments.map((item) => createOptionFromDocument(item, obj.dataSource.map));
1995
2269
  }
@@ -2032,15 +2306,21 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2032
2306
  if (!providerId || !providers[providerId]) return [];
2033
2307
  const schema = providers[providerId]?.schema;
2034
2308
  const layout = providers[providerId]?.layout;
2035
- const allProviderIds = [...findAllDataProviders(schema), ...findAllDataProviders(layout)];
2309
+ const dataSourceFilter = providers[providerId]?.dataSource?.filter;
2310
+ const allProviderIds = [
2311
+ ...findAllDataProviders(schema),
2312
+ ...findAllDataProviders(layout),
2313
+ ...collectSourceProviders(dataSourceFilter),
2314
+ ...collectSourceProviders(dataFilter)
2315
+ ];
2036
2316
  const uniqueProviders = {};
2037
2317
  allProviderIds.forEach((dataProvider) => {
2038
- const resolved = resolveProviderRef(dataProvider, providers, presetProviders, params);
2318
+ const resolved = resolveProviderRef2(dataProvider, providers, presetProviders, params);
2039
2319
  if (resolved.runtimeId === providerId) return;
2040
2320
  uniqueProviders[resolved.runtimeId] = resolved;
2041
2321
  });
2042
2322
  return Object.values(uniqueProviders);
2043
- }, [providerId, providerVersion, getExternalProviders, presetProviders, params]);
2323
+ }, [providerId, providerVersion, getExternalProviders, presetProviders, params, dataFilter]);
2044
2324
  const dependentProviderVersion = (0, import_react2.useSyncExternalStore)(
2045
2325
  (0, import_react2.useCallback)(
2046
2326
  (onStoreChange) => {
@@ -2097,7 +2377,7 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2097
2377
  dispatch("unregisterProvider", retId);
2098
2378
  }
2099
2379
  };
2100
- }, []);
2380
+ }, [id, params, dataFilter, dependentProviderVersion, dispatch, getExternalProviders, presetProviders, updateProviderListeners]);
2101
2381
  (0, import_react2.useEffect)(() => {
2102
2382
  if (dependentProviders.length === 0) return;
2103
2383
  const currentProviders = getExternalProviders();
@@ -2180,7 +2460,8 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2180
2460
  systemLog("usedp", "KonecVytvoreni dat: ", providerId);
2181
2461
  if (filter) {
2182
2462
  systemLog("usedp", "Jdu filterovat: ", JSON.stringify(filter));
2183
- docs = (0, import_json_filter.filterJsonDocuments)(docs, filter);
2463
+ const resolvedFilter = resolveDynamicValue(filter, { providers, documents, presetProviders, params });
2464
+ docs = (0, import_json_filter2.filterJsonDocuments)(docs, resolvedFilter);
2184
2465
  systemLog("usedp", "Konec filteru: ");
2185
2466
  }
2186
2467
  const schema = providers[providerId].schema;
@@ -2257,40 +2538,133 @@ var useDocument = ({ documentId, model, provider, fields, allFields }) => {
2257
2538
 
2258
2539
  // src/useProviderActions.tsx
2259
2540
  var import_react4 = require("react");
2541
+ var resolveProviderRef3 = (templateId, providers, presetProviders, data) => {
2542
+ if (providers[templateId]) {
2543
+ return { templateId, runtimeId: templateId };
2544
+ }
2545
+ if (presetProviders[templateId]) {
2546
+ const templateData = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
2547
+ const rendered = renderJSONTemplate(presetProviders[templateId], templateData);
2548
+ return { templateId, runtimeId: rendered.id };
2549
+ }
2550
+ return { templateId, runtimeId: templateId };
2551
+ };
2260
2552
  var useProviderActions = (providerId, data) => {
2261
2553
  const providers = (0, import_react4.useContext)(DataStoreProvidersContext);
2262
2554
  const { dispatch, presetProviders, updateProviderListeners } = (0, import_react4.useContext)(DataStoreActionsContext);
2555
+ const { subscribeToProvider, getProviderLastUpdate, getExternalProviders } = (0, import_react4.useContext)(DataStoreStableContext);
2263
2556
  const providerKey = providerId;
2557
+ const templateData = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
2558
+ const runtimeProviderRef = (0, import_react4.useMemo)(() => {
2559
+ const currentProviders = getExternalProviders();
2560
+ return resolveProviderRef3(providerKey, currentProviders, presetProviders, data);
2561
+ }, [providerKey, getExternalProviders, presetProviders, data]);
2562
+ const dependentProviders = (0, import_react4.useMemo)(() => {
2563
+ const currentProviders = getExternalProviders();
2564
+ const sourceFilter = currentProviders[runtimeProviderRef.runtimeId]?.dataSource?.filter ?? (runtimeProviderRef.runtimeId === providerKey ? presetProviders[providerKey]?.dataSource?.filter : void 0);
2565
+ const sourceProviderIds = collectSourceProviders(sourceFilter);
2566
+ const uniqueProviders = {};
2567
+ sourceProviderIds.forEach((itemId) => {
2568
+ const resolved = resolveProviderRef3(itemId, currentProviders, presetProviders, data);
2569
+ if (resolved.runtimeId === runtimeProviderRef.runtimeId) return;
2570
+ uniqueProviders[resolved.runtimeId] = resolved;
2571
+ });
2572
+ return Object.values(uniqueProviders);
2573
+ }, [runtimeProviderRef.runtimeId, providerKey, getExternalProviders, presetProviders, data]);
2574
+ const dependentProviderVersion = (0, import_react4.useSyncExternalStore)(
2575
+ (0, import_react4.useCallback)(
2576
+ (onStoreChange) => {
2577
+ if (dependentProviders.length === 0) return () => {
2578
+ };
2579
+ const unsubscribers = dependentProviders.map((providerRef) => subscribeToProvider(providerRef.runtimeId, onStoreChange));
2580
+ return () => {
2581
+ unsubscribers.forEach((unsubscribe) => unsubscribe?.());
2582
+ };
2583
+ },
2584
+ [dependentProviders, subscribeToProvider]
2585
+ ),
2586
+ (0, import_react4.useCallback)(() => {
2587
+ if (dependentProviders.length === 0) return "";
2588
+ return dependentProviders.map((providerRef) => String(getProviderLastUpdate(providerRef.runtimeId) ?? "")).join("|");
2589
+ }, [dependentProviders, getProviderLastUpdate]),
2590
+ () => ""
2591
+ );
2264
2592
  systemLog("usedp", `${providerId}`);
2265
2593
  (0, import_react4.useEffect)(() => {
2266
- if (providers[providerId]) {
2267
- systemLog("usedp", "Provider:", providerId, "existuje");
2268
- if (!providers[providerId].isPermanent) updateProviderListeners(providerId, 1);
2594
+ const runtimeId = runtimeProviderRef.runtimeId;
2595
+ const currentProviders = getExternalProviders();
2596
+ if (currentProviders[runtimeId]) {
2597
+ systemLog("usedp", "Provider:", runtimeId, "existuje");
2598
+ if (!currentProviders[runtimeId].isPermanent) updateProviderListeners(runtimeId, 1);
2269
2599
  } else {
2270
2600
  if (presetProviders[providerKey]) {
2271
- const templateData = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
2272
2601
  const prov = renderJSONTemplate(presetProviders[providerKey], templateData);
2273
- systemLog("usedp", "Registruji novy provider:", providerId);
2602
+ systemLog("usedp", "Registruji novy provider:", runtimeId);
2274
2603
  dispatch("registerProvider", prov);
2275
2604
  } else {
2276
- systemLog("usedp", "Neznamy provider ", providerId);
2605
+ systemLog("usedp", "Neznamy provider ", runtimeId);
2277
2606
  }
2278
- return () => {
2279
- if (!presetProviders[providerKey]?.isPermanent && !providers[providerId]?.isPermanent) {
2280
- dispatch("unregisterProvider", providerId);
2281
- }
2282
- };
2283
2607
  }
2284
- }, []);
2608
+ return () => {
2609
+ const activeProviders = getExternalProviders();
2610
+ if (!presetProviders[providerKey]?.isPermanent && !activeProviders[runtimeId]?.isPermanent) {
2611
+ dispatch("unregisterProvider", runtimeId);
2612
+ }
2613
+ };
2614
+ }, [
2615
+ providerKey,
2616
+ runtimeProviderRef.runtimeId,
2617
+ dependentProviderVersion,
2618
+ dispatch,
2619
+ getExternalProviders,
2620
+ presetProviders,
2621
+ templateData,
2622
+ updateProviderListeners
2623
+ ]);
2624
+ (0, import_react4.useEffect)(() => {
2625
+ if (dependentProviders.length === 0) return;
2626
+ const currentProviders = getExternalProviders();
2627
+ const incrementedProviders = [];
2628
+ const createdProviders = [];
2629
+ dependentProviders.forEach((providerRef) => {
2630
+ if (currentProviders[providerRef.runtimeId]) {
2631
+ if (!currentProviders[providerRef.runtimeId]?.isPermanent) {
2632
+ updateProviderListeners(providerRef.runtimeId, 1);
2633
+ incrementedProviders.push(providerRef.runtimeId);
2634
+ }
2635
+ return;
2636
+ }
2637
+ if (!presetProviders[providerRef.templateId]) return;
2638
+ const renderedProvider = renderJSONTemplate(presetProviders[providerRef.templateId], templateData);
2639
+ dispatch("registerProvider", renderedProvider);
2640
+ createdProviders.push({
2641
+ templateId: providerRef.templateId,
2642
+ runtimeId: renderedProvider.id
2643
+ });
2644
+ });
2645
+ return () => {
2646
+ incrementedProviders.forEach((id) => {
2647
+ updateProviderListeners(id, -1);
2648
+ });
2649
+ if (createdProviders.length === 0) return;
2650
+ const activeProviders = getExternalProviders();
2651
+ createdProviders.forEach((providerRef) => {
2652
+ const presetProvider = presetProviders[providerRef.templateId];
2653
+ if (!presetProvider?.isPermanent && !activeProviders[providerRef.runtimeId]?.isPermanent) {
2654
+ dispatch("unregisterProvider", providerRef.runtimeId);
2655
+ }
2656
+ });
2657
+ };
2658
+ }, [dependentProviders, dispatch, getExternalProviders, presetProviders, templateData, updateProviderListeners]);
2285
2659
  const update = (val) => {
2286
2660
  systemLog("usedp", "UPDATUJI: ", providerId, ", data: ", val);
2287
- dispatch("updateDataStore", { id: providerId, data: val });
2661
+ dispatch("updateDataStore", { id: runtimeProviderRef.runtimeId, data: val });
2288
2662
  };
2289
2663
  const updateItem = ({ params, data: data2, variant, documentId = void 0 }, callback) => {
2290
- dispatch("updateDataStore", { id: providerId, variant, params, data: data2, documentId }, callback);
2664
+ dispatch("updateDataStore", { id: runtimeProviderRef.runtimeId, variant, params, data: data2, documentId }, callback);
2291
2665
  };
2292
2666
  const deleteItem = ({ params, data: data2 }, callback) => {
2293
- dispatch("deleteProviderItem", { providerId, data: data2, params }, callback);
2667
+ dispatch("deleteProviderItem", { providerId: runtimeProviderRef.runtimeId, data: data2, params }, callback);
2294
2668
  };
2295
2669
  const createItem = ({
2296
2670
  data: data2,
@@ -2298,16 +2672,16 @@ var useProviderActions = (providerId, data) => {
2298
2672
  callback
2299
2673
  }) => {
2300
2674
  systemLog("usedp", "createItem Prov. id:", providerId);
2301
- return new Promise((resolve, reject) => {
2675
+ return new Promise((resolve) => {
2302
2676
  const wrappedCallback = (result) => {
2303
2677
  callback?.(result);
2304
2678
  resolve(result);
2305
2679
  };
2306
- dispatch("createProviderItem", { id: providerId, data: data2, variant }, wrappedCallback);
2680
+ dispatch("createProviderItem", { id: runtimeProviderRef.runtimeId, data: data2, variant }, wrappedCallback);
2307
2681
  });
2308
2682
  };
2309
2683
  return {
2310
- schema: providers[providerId]?.schema,
2684
+ schema: providers[runtimeProviderRef.runtimeId]?.schema,
2311
2685
  update,
2312
2686
  updateItem,
2313
2687
  deleteItem,