@mgarlik/datastore 0.1.26 → 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.js CHANGED
@@ -665,7 +665,14 @@ var getData = async ({ id, dataSource, isPersisting, schema, SQLite, changeTime
665
665
  }).filter((item) => item !== null);
666
666
  }
667
667
  if (dataSource) {
668
- const axiosResponse = await axios.get(buildUri({ dataSource, method: "read" }), { params: serializeParams(params) });
668
+ const serializedParams = serializeParams(params);
669
+ console.log("[HANDLE DATA] outgoing read params", buildUri({ dataSource, method: "read" }), serializedParams);
670
+ console.assert(
671
+ !(typeof serializedParams.filter === "string" && serializedParams.filter.includes('"$source"')),
672
+ "[HANDLE DATA] unresolved $source reached outgoing filter",
673
+ serializedParams.filter
674
+ );
675
+ const axiosResponse = await axios.get(buildUri({ dataSource, method: "read" }), { params: serializedParams });
669
676
  if (schema && !dataSource.readAllFields) {
670
677
  const mapBySchema = (element) => {
671
678
  const mappedRow = {};
@@ -750,9 +757,8 @@ var deleteData = async ({ dataSource, data }) => {
750
757
  }
751
758
  };
752
759
 
753
- // src/DataStoreProvider.tsx
754
- import { io as ioSockets } from "socket.io-client";
755
- import axios2 from "axios";
760
+ // src/sourceResolution.ts
761
+ import { filterJsonDocuments as filterDocuments2 } from "@mgarlik/json-filter";
756
762
 
757
763
  // src/templates.ts
758
764
  var _renderMyTemplate = (templateString, data) => {
@@ -781,7 +787,84 @@ function renderJSONTemplate(val, data) {
781
787
  return parsedObj;
782
788
  }
783
789
 
790
+ // src/sourceResolution.ts
791
+ var resolveProviderRef = (providerId, providers, presetProviders, params) => {
792
+ if (providers[providerId]) {
793
+ return { templateId: providerId, runtimeId: providerId };
794
+ }
795
+ if (presetProviders[providerId]) {
796
+ const renderedProvider = renderJSONTemplate(presetProviders[providerId], params ?? void 0);
797
+ return { templateId: providerId, runtimeId: renderedProvider.id };
798
+ }
799
+ return null;
800
+ };
801
+ var collectObjectSourceProviders = (obj, result) => {
802
+ if (!obj || typeof obj !== "object") return;
803
+ if (Array.isArray(obj)) {
804
+ obj.forEach((item) => collectObjectSourceProviders(item, result));
805
+ return;
806
+ }
807
+ if (obj.$source?.dataProvider) {
808
+ result.add(String(obj.$source.dataProvider));
809
+ }
810
+ if (obj.dataSource?.dataProvider) {
811
+ result.add(String(obj.dataSource.dataProvider));
812
+ }
813
+ Object.values(obj).forEach((value) => collectObjectSourceProviders(value, result));
814
+ };
815
+ var collectSourceProviders = (value) => {
816
+ const result = /* @__PURE__ */ new Set();
817
+ collectObjectSourceProviders(value, result);
818
+ return Array.from(result);
819
+ };
820
+ var resolveDynamicValue = (value, context, stack = []) => {
821
+ if (value === null || value === void 0) return value;
822
+ if (Array.isArray(value)) {
823
+ return value.map((item) => resolveDynamicValue(item, context, stack));
824
+ }
825
+ if (typeof value !== "object") return value;
826
+ const sourceKeys = Object.keys(value);
827
+ if (sourceKeys.length === 1 && sourceKeys[0] === "$source") {
828
+ return resolveSourceConfig(value.$source, context, stack);
829
+ }
830
+ const result = {};
831
+ for (const [key, item] of Object.entries(value)) {
832
+ result[key] = resolveDynamicValue(item, context, stack);
833
+ }
834
+ return result;
835
+ };
836
+ var resolveSourceConfig = (source, context, stack = []) => {
837
+ if (!source?.dataProvider) return source?.val ? null : void 0;
838
+ const resolvedRef = resolveProviderRef(source.dataProvider, context.providers, context.presetProviders, context.params);
839
+ if (!resolvedRef) return source.val ? null : void 0;
840
+ if (stack.includes(resolvedRef.runtimeId)) {
841
+ throw new Error(`Cyclic $source reference detected for provider ${resolvedRef.runtimeId}`);
842
+ }
843
+ const provider = context.providers[resolvedRef.runtimeId];
844
+ if (!provider) return source.map ? [] : source.val ? null : void 0;
845
+ const providerDocuments = Array.isArray(provider.data) ? provider.data.map((docId) => {
846
+ const doc = context.documents[docId];
847
+ if (!doc) return null;
848
+ return { id: docId, ...doc };
849
+ }).filter((item) => item !== null) : [];
850
+ const resolvedFilter = source.filter ? resolveDynamicValue(source.filter, context, [...stack, resolvedRef.runtimeId]) : void 0;
851
+ const filteredDocuments = resolvedFilter ? filterDocuments2(providerDocuments, resolvedFilter) : providerDocuments;
852
+ if (source.map) {
853
+ return filteredDocuments.map((item) => getValueByDotPath(item, source.map)).filter((item) => item !== void 0);
854
+ }
855
+ if (source.val) {
856
+ if (filteredDocuments.length === 0) return null;
857
+ if (filteredDocuments.length > 1) {
858
+ throw new Error(`$source.val expects exactly one document from ${source.dataProvider}, got ${filteredDocuments.length}`);
859
+ }
860
+ return getValueByDotPath(filteredDocuments[0], source.val) ?? null;
861
+ }
862
+ return filteredDocuments;
863
+ };
864
+
784
865
  // src/DataStoreProvider.tsx
866
+ import { io as ioSockets } from "socket.io-client";
867
+ import axios2 from "axios";
785
868
  import isEqual from "lodash/isEqual.js";
786
869
  import { jsx } from "react/jsx-runtime";
787
870
  var DataStoreContext = createContext({});
@@ -816,11 +899,13 @@ var useDocuments = () => {
816
899
  var useProviderDocuments = (provider, settings) => {
817
900
  const documents = useContext(DataStoreDocumentsContext);
818
901
  const providers = useContext(DataStoreProvidersContext);
902
+ const presetProviders = useContext(DataStoreStableContext).presetProviders;
903
+ const resolvedFilter = settings?.filter ? resolveDynamicValue(settings.filter, { providers, documents, presetProviders }) : void 0;
819
904
  const docs = useMemo(() => {
820
905
  console.log("useProviderDocuments", provider);
821
906
  const d = {};
822
907
  providers[provider]?.data.forEach((id) => {
823
- if (settings?.filter && !doesObjectMatchFilter(documents[id], settings.filter)) return;
908
+ if (resolvedFilter && !doesObjectMatchFilter(documents[id], resolvedFilter)) return;
824
909
  let result = documents[id];
825
910
  if (providers[provider].depend) {
826
911
  result = recalculateObjectWithDocument(documents[id], documents[providers[provider].depend]);
@@ -832,7 +917,16 @@ var useProviderDocuments = (provider, settings) => {
832
917
  d[id] = result;
833
918
  });
834
919
  return d;
835
- }, [providers[provider]?.lastUpdate, documents[providers[provider]?.depend], settings?.filter, settings?.documentId, settings?.document]);
920
+ }, [
921
+ providers[provider]?.lastUpdate,
922
+ documents[providers[provider]?.depend],
923
+ settings?.filter,
924
+ settings?.documentId,
925
+ settings?.document,
926
+ providers,
927
+ documents,
928
+ presetProviders
929
+ ]);
836
930
  return { documents: docs };
837
931
  };
838
932
  var useProvider = (val) => {
@@ -892,6 +986,8 @@ var DataStoreProvider = forwardRef(
892
986
  const [counterProviders, setCounterProviders] = useState({});
893
987
  const [counterDocuments, setCounterDocuments] = useState({});
894
988
  const didInitialLiveSyncRef = useRef(false);
989
+ const providerDynamicSourceStateRef = useRef({});
990
+ const providerDynamicRefreshInProgressRef = useRef(/* @__PURE__ */ new Set());
895
991
  const persistenceStorage = useMemo(
896
992
  () => usePersistentStorage ? storage : null,
897
993
  [storage, usePersistentStorage]
@@ -1007,6 +1103,7 @@ var DataStoreProvider = forwardRef(
1007
1103
  const response = await getData({
1008
1104
  id: key,
1009
1105
  ...rest,
1106
+ dataSource: resolveDynamicValue(rest.dataSource || {}, { providers, documents, presetProviders }),
1010
1107
  changeTime: lastUpdate.time
1011
1108
  });
1012
1109
  if (response.length > 0) {
@@ -1291,7 +1388,10 @@ var DataStoreProvider = forwardRef(
1291
1388
  if (dP) {
1292
1389
  const dataFromSource = await getData({
1293
1390
  id: dP.id,
1294
- dataSource: { ...dP.dataSource, params: { select: fields.join(" ") } },
1391
+ dataSource: resolveDynamicValue(
1392
+ { ...dP.dataSource, params: { select: fields.join(" ") } },
1393
+ { providers, documents, presetProviders }
1394
+ ),
1295
1395
  isPersisting: !!dP.isPersisting && !!persistenceStorage,
1296
1396
  schema: dP.schema,
1297
1397
  SQLite: persistenceStorage || void 0
@@ -1314,9 +1414,10 @@ var DataStoreProvider = forwardRef(
1314
1414
  data: Array.isArray(provider?.data) ? [...provider.data] : []
1315
1415
  };
1316
1416
  var socketListeners = providerNext.dataSource?.socketListeners || [];
1417
+ const resolvedProviderFilter = providerNext.dataSource?.filter ? resolveDynamicValue(providerNext.dataSource.filter, { providers, documents, presetProviders }) : void 0;
1317
1418
  if (socketListeners.length === 0) {
1318
1419
  if (providerNext.data.includes(documentId)) {
1319
- if (!providerNext.dataSource?.filter || filterDocuments(documentForFilter, providerNext.dataSource?.filter)) {
1420
+ if (!resolvedProviderFilter || filterDocuments(documentForFilter, resolvedProviderFilter)) {
1320
1421
  listeningProviders++;
1321
1422
  providerNext.lastUpdate = {
1322
1423
  id: uuid(),
@@ -1335,7 +1436,7 @@ var DataStoreProvider = forwardRef(
1335
1436
  }
1336
1437
  } else if (socketListeners.includes(model) || // socketListeners.includes(documentId) ||
1337
1438
  key === model) {
1338
- if (!providerNext.dataSource.filter || filterDocuments(documentForFilter, providerNext.dataSource.filter)) {
1439
+ if (!resolvedProviderFilter || filterDocuments(documentForFilter, resolvedProviderFilter)) {
1339
1440
  listeningProviders++;
1340
1441
  providerNext.lastUpdate = {
1341
1442
  id: uuid(),
@@ -1454,7 +1555,8 @@ var DataStoreProvider = forwardRef(
1454
1555
  Object.keys(providers).forEach((key) => {
1455
1556
  const provider = providers[key];
1456
1557
  var socketListeners = provider.dataSource?.socketListeners;
1457
- if ((socketListeners?.includes(model) || key === model) && (!provider.dataSource?.filter || filterDocuments(newDocument, provider.dataSource?.filter))) {
1558
+ const resolvedProviderFilter = provider.dataSource?.filter ? resolveDynamicValue(provider.dataSource.filter, { providers, documents, presetProviders }) : void 0;
1559
+ if ((socketListeners?.includes(model) || key === model) && (!resolvedProviderFilter || filterDocuments(newDocument, resolvedProviderFilter))) {
1458
1560
  if (!provider.data.includes(documentId)) {
1459
1561
  setCounterDocuments((prev) => {
1460
1562
  const newC = { ...prev };
@@ -1617,6 +1719,171 @@ var DataStoreProvider = forwardRef(
1617
1719
  },
1618
1720
  [setSockets, socket]
1619
1721
  );
1722
+ const buildResolvedDataSourceSnapshot = useCallback(
1723
+ (providerId) => {
1724
+ const provider = providers[providerId];
1725
+ if (!provider?.dataSource) return null;
1726
+ const dependencies = collectSourceProviders(provider.dataSource);
1727
+ if (dependencies.length === 0) return null;
1728
+ const resolvedDataSource = resolveDynamicValue(provider.dataSource, { providers, documents, presetProviders });
1729
+ return {
1730
+ resolvedDataSource,
1731
+ signature: JSON.stringify(resolvedDataSource ?? {}),
1732
+ socketFilter: resolvedDataSource?.filter ?? {}
1733
+ };
1734
+ },
1735
+ [providers, documents, presetProviders]
1736
+ );
1737
+ const refreshProviderFromResolvedDataSource = useCallback(
1738
+ async (providerId, resolvedDataSource, resolvedSocketFilter) => {
1739
+ const provider = providers[providerId];
1740
+ if (!provider) return;
1741
+ console.log("[DSP][dynamic] reload start", {
1742
+ providerId,
1743
+ previousCount: Array.isArray(provider.data) ? provider.data.length : 0
1744
+ });
1745
+ const dataFromSource = await getData({
1746
+ schema: provider.schema,
1747
+ dataSource: resolvedDataSource,
1748
+ id: providerId,
1749
+ isPersisting: !!provider.isPersisting && !!persistenceStorage,
1750
+ SQLite: persistenceStorage || void 0
1751
+ });
1752
+ const nextDocumentIds = [];
1753
+ const nextDocuments = {};
1754
+ const sourceItems = Array.isArray(dataFromSource) ? dataFromSource : [dataFromSource];
1755
+ sourceItems.forEach((item) => {
1756
+ if (!item || typeof item !== "object") return;
1757
+ const { id, ...data } = item;
1758
+ const normalizedId = id || uuid();
1759
+ nextDocumentIds.push(normalizedId);
1760
+ nextDocuments[normalizedId] = documents[normalizedId] ? { ...documents[normalizedId], ...data } : data;
1761
+ });
1762
+ const previousDocumentIds = Array.isArray(provider.data) ? provider.data : [];
1763
+ const previousSet = new Set(previousDocumentIds);
1764
+ const nextSet = new Set(nextDocumentIds);
1765
+ const addedDocumentIds = nextDocumentIds.filter((itemId) => !previousSet.has(itemId));
1766
+ const removedDocumentIds = previousDocumentIds.filter((itemId) => !nextSet.has(itemId));
1767
+ setCounterDocuments((prev) => {
1768
+ const nextCounters = { ...prev };
1769
+ const documentsToDelete = [];
1770
+ removedDocumentIds.forEach((itemId) => {
1771
+ if (!nextCounters[itemId] || nextCounters[itemId] <= 1) {
1772
+ delete nextCounters[itemId];
1773
+ documentsToDelete.push(itemId);
1774
+ } else {
1775
+ nextCounters[itemId] = nextCounters[itemId] - 1;
1776
+ }
1777
+ });
1778
+ addedDocumentIds.forEach((itemId) => {
1779
+ nextCounters[itemId] = (nextCounters[itemId] || 0) + 1;
1780
+ });
1781
+ setDocuments((prevDocs) => {
1782
+ const nextDocs = { ...prevDocs };
1783
+ documentsToDelete.forEach((itemId) => {
1784
+ delete nextDocs[itemId];
1785
+ });
1786
+ Object.entries(nextDocuments).forEach(([itemId, itemData]) => {
1787
+ nextDocs[itemId] = itemData;
1788
+ });
1789
+ return nextDocs;
1790
+ });
1791
+ return nextCounters;
1792
+ });
1793
+ setProviders((prev) => {
1794
+ if (!prev[providerId]) return prev;
1795
+ return {
1796
+ ...prev,
1797
+ [providerId]: {
1798
+ ...prev[providerId],
1799
+ data: nextDocumentIds,
1800
+ _resolvedSocketFilter: resolvedSocketFilter,
1801
+ lastUpdate: { id: uuid(), time: /* @__PURE__ */ new Date() }
1802
+ }
1803
+ };
1804
+ });
1805
+ console.log("[DSP][dynamic] reload done", {
1806
+ providerId,
1807
+ nextCount: nextDocumentIds.length,
1808
+ added: addedDocumentIds.length,
1809
+ removed: removedDocumentIds.length,
1810
+ socketFilter: resolvedSocketFilter
1811
+ });
1812
+ if (provider?.isPersisting && persistenceStorage) {
1813
+ await Promise.all(removedDocumentIds.map((itemId) => removePersistedDocument(itemId)));
1814
+ await Promise.all(
1815
+ Object.entries(nextDocuments).map(
1816
+ ([itemId, itemData]) => persistDocument({ documentId: itemId, model: providerId, data: itemData })
1817
+ )
1818
+ );
1819
+ }
1820
+ },
1821
+ [providers, documents, persistenceStorage, removePersistedDocument, persistDocument]
1822
+ );
1823
+ useEffect(() => {
1824
+ const trackedProviderIds = Object.keys(providers).filter((providerId) => {
1825
+ const provider = providers[providerId];
1826
+ return !!provider?.dataSource && collectSourceProviders(provider.dataSource).length > 0;
1827
+ });
1828
+ const trackedSet = new Set(trackedProviderIds);
1829
+ Object.keys(providerDynamicSourceStateRef.current).forEach((providerId) => {
1830
+ if (!trackedSet.has(providerId)) {
1831
+ delete providerDynamicSourceStateRef.current[providerId];
1832
+ }
1833
+ });
1834
+ trackedProviderIds.forEach((providerId) => {
1835
+ const snapshot = buildResolvedDataSourceSnapshot(providerId);
1836
+ if (!snapshot) return;
1837
+ const previousSnapshot = providerDynamicSourceStateRef.current[providerId];
1838
+ if (!previousSnapshot) {
1839
+ providerDynamicSourceStateRef.current[providerId] = {
1840
+ signature: snapshot.signature,
1841
+ socketFilter: snapshot.socketFilter
1842
+ };
1843
+ return;
1844
+ }
1845
+ if (previousSnapshot.signature === snapshot.signature) return;
1846
+ if (providerDynamicRefreshInProgressRef.current.has(providerId)) return;
1847
+ console.log("[DSP][dynamic] dataSource changed", {
1848
+ providerId,
1849
+ previousFilter: previousSnapshot.socketFilter,
1850
+ nextFilter: snapshot.socketFilter
1851
+ });
1852
+ providerDynamicSourceStateRef.current[providerId] = {
1853
+ signature: snapshot.signature,
1854
+ socketFilter: snapshot.socketFilter
1855
+ };
1856
+ providerDynamicRefreshInProgressRef.current.add(providerId);
1857
+ const provider = providers[providerId];
1858
+ const socketListeners = provider?.dataSource?.socketListeners;
1859
+ (async () => {
1860
+ try {
1861
+ if (socketListeners && !isEqual(previousSnapshot.socketFilter, snapshot.socketFilter)) {
1862
+ console.log("[DSP][dynamic] socket filter refresh", {
1863
+ providerId,
1864
+ socketListeners,
1865
+ previousFilter: previousSnapshot.socketFilter,
1866
+ nextFilter: snapshot.socketFilter
1867
+ });
1868
+ unregisterProviderSockets(socketListeners, previousSnapshot.socketFilter);
1869
+ registerProviderSockets(socketListeners, snapshot.socketFilter);
1870
+ }
1871
+ await refreshProviderFromResolvedDataSource(providerId, snapshot.resolvedDataSource, snapshot.socketFilter);
1872
+ } catch (error) {
1873
+ console.error("[DataStoreProvider] dynamic dataSource refresh error", { providerId, error });
1874
+ } finally {
1875
+ providerDynamicRefreshInProgressRef.current.delete(providerId);
1876
+ }
1877
+ })();
1878
+ });
1879
+ }, [
1880
+ providers,
1881
+ documents,
1882
+ buildResolvedDataSourceSnapshot,
1883
+ refreshProviderFromResolvedDataSource,
1884
+ registerProviderSockets,
1885
+ unregisterProviderSockets
1886
+ ]);
1620
1887
  const updateProviderListeners = useCallback(
1621
1888
  async (id, val) => {
1622
1889
  setCounterProviders((prev) => {
@@ -1629,7 +1896,7 @@ var DataStoreProvider = forwardRef(
1629
1896
  const newS = { ...prevS };
1630
1897
  const removeSocketListeners = [];
1631
1898
  const providerSocketListeners = prevP[id].dataSource?.socketListeners || [];
1632
- const providerFilter = prevP[id].dataSource?.filter;
1899
+ const providerFilter = prevP[id]._resolvedSocketFilter ?? prevP[id].dataSource?.filter;
1633
1900
  const normalizedFilter = providerFilter ?? {};
1634
1901
  providerSocketListeners.forEach((socketName) => {
1635
1902
  if (!newS[socketName]) return;
@@ -1693,9 +1960,10 @@ var DataStoreProvider = forwardRef(
1693
1960
  result = providers[id];
1694
1961
  } else {
1695
1962
  try {
1963
+ const resolvedDataSource = resolveDynamicValue(newItem.dataSource || {}, { providers, documents, presetProviders });
1696
1964
  const dataFromSource = await getData({
1697
1965
  schema: newItem.schema,
1698
- dataSource: newItem.dataSource || {},
1966
+ dataSource: resolvedDataSource,
1699
1967
  id: newItem.id,
1700
1968
  isPersisting: !!newItem.isPersisting && !!persistenceStorage,
1701
1969
  SQLite: persistenceStorage || void 0
@@ -1734,6 +2002,7 @@ var DataStoreProvider = forwardRef(
1734
2002
  result = {
1735
2003
  ...provider,
1736
2004
  data: dataList,
2005
+ _resolvedSocketFilter: resolvedDataSource?.filter ?? {},
1737
2006
  lastUpdate: { id: uuid(), time: /* @__PURE__ */ new Date() }
1738
2007
  };
1739
2008
  setProviders((prev) => ({
@@ -1746,7 +2015,7 @@ var DataStoreProvider = forwardRef(
1746
2015
  }));
1747
2016
  if (provider.dataSource?.socketListeners) {
1748
2017
  console.log("TATATATA");
1749
- registerProviderSockets(provider.dataSource.socketListeners, provider.dataSource.filter);
2018
+ registerProviderSockets(provider.dataSource.socketListeners, resolvedDataSource?.filter ?? {});
1750
2019
  }
1751
2020
  } catch (error) {
1752
2021
  console.error("[DataStoreProvider] registerProvider:error", { id: newItem.id, error });
@@ -1767,7 +2036,10 @@ var DataStoreProvider = forwardRef(
1767
2036
  [itemId]: prev[itemId] - 1
1768
2037
  };
1769
2038
  } else {
1770
- unregisterProviderSockets(providers[itemId]?.dataSource.socketListeners, providers[itemId]?.dataSource.filter);
2039
+ unregisterProviderSockets(
2040
+ providers[itemId]?.dataSource.socketListeners,
2041
+ providers[itemId]?._resolvedSocketFilter ?? providers[itemId]?.dataSource.filter
2042
+ );
1771
2043
  setCounterDocuments((cd) => {
1772
2044
  const newC = { ...cd };
1773
2045
  const deleteDocumentIds = [];
@@ -1869,14 +2141,15 @@ var DataStoreProvider_default = DataStoreProvider;
1869
2141
 
1870
2142
  // src/useDataProvider.tsx
1871
2143
  import { useCallback as useCallback2, useContext as useContext2, useEffect as useEffect2, useMemo as useMemo2, useState as useState2, useSyncExternalStore } from "react";
1872
- import { filterJsonDocuments as filterDocuments2 } from "@mgarlik/json-filter";
2144
+ import { filterJsonDocuments as filterDocuments3 } from "@mgarlik/json-filter";
1873
2145
  var findAllDataProviders = (obj) => {
1874
2146
  if (!obj || typeof obj !== "object") return [];
1875
2147
  if (obj.dataSource?.dataProvider) return [obj.dataSource.dataProvider];
2148
+ if (obj.$source?.dataProvider) return [obj.$source.dataProvider];
1876
2149
  if (Array.isArray(obj)) return obj.flatMap(findAllDataProviders);
1877
2150
  return Object.values(obj).flatMap(findAllDataProviders);
1878
2151
  };
1879
- var resolveProviderRef = (providerId, providers, presetProviders, params) => {
2152
+ var resolveProviderRef2 = (providerId, providers, presetProviders, params) => {
1880
2153
  if (providers[providerId]) {
1881
2154
  return { templateId: providerId, runtimeId: providerId };
1882
2155
  }
@@ -1907,7 +2180,7 @@ var createOptionFromDocument = (doc, map) => {
1907
2180
  var resolveDataSourcesDeep = (obj, providers, documents, presetProviders, params, logLabel = "options") => {
1908
2181
  if (!obj || typeof obj !== "object") return obj;
1909
2182
  if (obj.dataSource?.dataProvider) {
1910
- const providerRef = resolveProviderRef(obj.dataSource.dataProvider, providers, presetProviders, params);
2183
+ const providerRef = resolveProviderRef2(obj.dataSource.dataProvider, providers, presetProviders, params);
1911
2184
  const optionProvider = providers[providerRef.runtimeId];
1912
2185
  if (!optionProvider) {
1913
2186
  systemLog("usedp", `Nenalezen provider pro ${logLabel}`, obj.dataSource.dataProvider);
@@ -1919,7 +2192,8 @@ var resolveDataSourcesDeep = (obj, providers, documents, presetProviders, params
1919
2192
  return { id: docId, ...docData };
1920
2193
  }).filter((item) => !!item);
1921
2194
  if (obj.dataSource.filter) {
1922
- optionDocuments = filterDocuments2(optionDocuments, obj.dataSource.filter);
2195
+ const resolvedFilter = resolveDynamicValue(obj.dataSource.filter, { providers, documents, presetProviders, params });
2196
+ optionDocuments = filterDocuments3(optionDocuments, resolvedFilter);
1923
2197
  }
1924
2198
  return optionDocuments.map((item) => createOptionFromDocument(item, obj.dataSource.map));
1925
2199
  }
@@ -1962,15 +2236,21 @@ var useDataProvider = (id, params, dataFilter, settings) => {
1962
2236
  if (!providerId || !providers[providerId]) return [];
1963
2237
  const schema = providers[providerId]?.schema;
1964
2238
  const layout = providers[providerId]?.layout;
1965
- const allProviderIds = [...findAllDataProviders(schema), ...findAllDataProviders(layout)];
2239
+ const dataSourceFilter = providers[providerId]?.dataSource?.filter;
2240
+ const allProviderIds = [
2241
+ ...findAllDataProviders(schema),
2242
+ ...findAllDataProviders(layout),
2243
+ ...collectSourceProviders(dataSourceFilter),
2244
+ ...collectSourceProviders(dataFilter)
2245
+ ];
1966
2246
  const uniqueProviders = {};
1967
2247
  allProviderIds.forEach((dataProvider) => {
1968
- const resolved = resolveProviderRef(dataProvider, providers, presetProviders, params);
2248
+ const resolved = resolveProviderRef2(dataProvider, providers, presetProviders, params);
1969
2249
  if (resolved.runtimeId === providerId) return;
1970
2250
  uniqueProviders[resolved.runtimeId] = resolved;
1971
2251
  });
1972
2252
  return Object.values(uniqueProviders);
1973
- }, [providerId, providerVersion, getExternalProviders, presetProviders, params]);
2253
+ }, [providerId, providerVersion, getExternalProviders, presetProviders, params, dataFilter]);
1974
2254
  const dependentProviderVersion = useSyncExternalStore(
1975
2255
  useCallback2(
1976
2256
  (onStoreChange) => {
@@ -2027,7 +2307,7 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2027
2307
  dispatch("unregisterProvider", retId);
2028
2308
  }
2029
2309
  };
2030
- }, []);
2310
+ }, [id, params, dataFilter, dependentProviderVersion, dispatch, getExternalProviders, presetProviders, updateProviderListeners]);
2031
2311
  useEffect2(() => {
2032
2312
  if (dependentProviders.length === 0) return;
2033
2313
  const currentProviders = getExternalProviders();
@@ -2110,7 +2390,8 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2110
2390
  systemLog("usedp", "KonecVytvoreni dat: ", providerId);
2111
2391
  if (filter) {
2112
2392
  systemLog("usedp", "Jdu filterovat: ", JSON.stringify(filter));
2113
- docs = filterDocuments2(docs, filter);
2393
+ const resolvedFilter = resolveDynamicValue(filter, { providers, documents, presetProviders, params });
2394
+ docs = filterDocuments3(docs, resolvedFilter);
2114
2395
  systemLog("usedp", "Konec filteru: ");
2115
2396
  }
2116
2397
  const schema = providers[providerId].schema;
@@ -2186,41 +2467,134 @@ var useDocument = ({ documentId, model, provider, fields, allFields }) => {
2186
2467
  };
2187
2468
 
2188
2469
  // src/useProviderActions.tsx
2189
- import { useContext as useContext4, useEffect as useEffect4 } from "react";
2470
+ import { useCallback as useCallback3, useContext as useContext4, useEffect as useEffect4, useMemo as useMemo4, useSyncExternalStore as useSyncExternalStore2 } from "react";
2471
+ var resolveProviderRef3 = (templateId, providers, presetProviders, data) => {
2472
+ if (providers[templateId]) {
2473
+ return { templateId, runtimeId: templateId };
2474
+ }
2475
+ if (presetProviders[templateId]) {
2476
+ const templateData = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
2477
+ const rendered = renderJSONTemplate(presetProviders[templateId], templateData);
2478
+ return { templateId, runtimeId: rendered.id };
2479
+ }
2480
+ return { templateId, runtimeId: templateId };
2481
+ };
2190
2482
  var useProviderActions = (providerId, data) => {
2191
2483
  const providers = useContext4(DataStoreProvidersContext);
2192
2484
  const { dispatch, presetProviders, updateProviderListeners } = useContext4(DataStoreActionsContext);
2485
+ const { subscribeToProvider, getProviderLastUpdate, getExternalProviders } = useContext4(DataStoreStableContext);
2193
2486
  const providerKey = providerId;
2487
+ const templateData = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
2488
+ const runtimeProviderRef = useMemo4(() => {
2489
+ const currentProviders = getExternalProviders();
2490
+ return resolveProviderRef3(providerKey, currentProviders, presetProviders, data);
2491
+ }, [providerKey, getExternalProviders, presetProviders, data]);
2492
+ const dependentProviders = useMemo4(() => {
2493
+ const currentProviders = getExternalProviders();
2494
+ const sourceFilter = currentProviders[runtimeProviderRef.runtimeId]?.dataSource?.filter ?? (runtimeProviderRef.runtimeId === providerKey ? presetProviders[providerKey]?.dataSource?.filter : void 0);
2495
+ const sourceProviderIds = collectSourceProviders(sourceFilter);
2496
+ const uniqueProviders = {};
2497
+ sourceProviderIds.forEach((itemId) => {
2498
+ const resolved = resolveProviderRef3(itemId, currentProviders, presetProviders, data);
2499
+ if (resolved.runtimeId === runtimeProviderRef.runtimeId) return;
2500
+ uniqueProviders[resolved.runtimeId] = resolved;
2501
+ });
2502
+ return Object.values(uniqueProviders);
2503
+ }, [runtimeProviderRef.runtimeId, providerKey, getExternalProviders, presetProviders, data]);
2504
+ const dependentProviderVersion = useSyncExternalStore2(
2505
+ useCallback3(
2506
+ (onStoreChange) => {
2507
+ if (dependentProviders.length === 0) return () => {
2508
+ };
2509
+ const unsubscribers = dependentProviders.map((providerRef) => subscribeToProvider(providerRef.runtimeId, onStoreChange));
2510
+ return () => {
2511
+ unsubscribers.forEach((unsubscribe) => unsubscribe?.());
2512
+ };
2513
+ },
2514
+ [dependentProviders, subscribeToProvider]
2515
+ ),
2516
+ useCallback3(() => {
2517
+ if (dependentProviders.length === 0) return "";
2518
+ return dependentProviders.map((providerRef) => String(getProviderLastUpdate(providerRef.runtimeId) ?? "")).join("|");
2519
+ }, [dependentProviders, getProviderLastUpdate]),
2520
+ () => ""
2521
+ );
2194
2522
  systemLog("usedp", `${providerId}`);
2195
2523
  useEffect4(() => {
2196
- if (providers[providerId]) {
2197
- systemLog("usedp", "Provider:", providerId, "existuje");
2198
- if (!providers[providerId].isPermanent) updateProviderListeners(providerId, 1);
2524
+ const runtimeId = runtimeProviderRef.runtimeId;
2525
+ const currentProviders = getExternalProviders();
2526
+ if (currentProviders[runtimeId]) {
2527
+ systemLog("usedp", "Provider:", runtimeId, "existuje");
2528
+ if (!currentProviders[runtimeId].isPermanent) updateProviderListeners(runtimeId, 1);
2199
2529
  } else {
2200
2530
  if (presetProviders[providerKey]) {
2201
- const templateData = typeof data === "object" && data !== null && !Array.isArray(data) ? data : void 0;
2202
2531
  const prov = renderJSONTemplate(presetProviders[providerKey], templateData);
2203
- systemLog("usedp", "Registruji novy provider:", providerId);
2532
+ systemLog("usedp", "Registruji novy provider:", runtimeId);
2204
2533
  dispatch("registerProvider", prov);
2205
2534
  } else {
2206
- systemLog("usedp", "Neznamy provider ", providerId);
2535
+ systemLog("usedp", "Neznamy provider ", runtimeId);
2207
2536
  }
2208
- return () => {
2209
- if (!presetProviders[providerKey]?.isPermanent && !providers[providerId]?.isPermanent) {
2210
- dispatch("unregisterProvider", providerId);
2211
- }
2212
- };
2213
2537
  }
2214
- }, []);
2538
+ return () => {
2539
+ const activeProviders = getExternalProviders();
2540
+ if (!presetProviders[providerKey]?.isPermanent && !activeProviders[runtimeId]?.isPermanent) {
2541
+ dispatch("unregisterProvider", runtimeId);
2542
+ }
2543
+ };
2544
+ }, [
2545
+ providerKey,
2546
+ runtimeProviderRef.runtimeId,
2547
+ dependentProviderVersion,
2548
+ dispatch,
2549
+ getExternalProviders,
2550
+ presetProviders,
2551
+ templateData,
2552
+ updateProviderListeners
2553
+ ]);
2554
+ useEffect4(() => {
2555
+ if (dependentProviders.length === 0) return;
2556
+ const currentProviders = getExternalProviders();
2557
+ const incrementedProviders = [];
2558
+ const createdProviders = [];
2559
+ dependentProviders.forEach((providerRef) => {
2560
+ if (currentProviders[providerRef.runtimeId]) {
2561
+ if (!currentProviders[providerRef.runtimeId]?.isPermanent) {
2562
+ updateProviderListeners(providerRef.runtimeId, 1);
2563
+ incrementedProviders.push(providerRef.runtimeId);
2564
+ }
2565
+ return;
2566
+ }
2567
+ if (!presetProviders[providerRef.templateId]) return;
2568
+ const renderedProvider = renderJSONTemplate(presetProviders[providerRef.templateId], templateData);
2569
+ dispatch("registerProvider", renderedProvider);
2570
+ createdProviders.push({
2571
+ templateId: providerRef.templateId,
2572
+ runtimeId: renderedProvider.id
2573
+ });
2574
+ });
2575
+ return () => {
2576
+ incrementedProviders.forEach((id) => {
2577
+ updateProviderListeners(id, -1);
2578
+ });
2579
+ if (createdProviders.length === 0) return;
2580
+ const activeProviders = getExternalProviders();
2581
+ createdProviders.forEach((providerRef) => {
2582
+ const presetProvider = presetProviders[providerRef.templateId];
2583
+ if (!presetProvider?.isPermanent && !activeProviders[providerRef.runtimeId]?.isPermanent) {
2584
+ dispatch("unregisterProvider", providerRef.runtimeId);
2585
+ }
2586
+ });
2587
+ };
2588
+ }, [dependentProviders, dispatch, getExternalProviders, presetProviders, templateData, updateProviderListeners]);
2215
2589
  const update = (val) => {
2216
2590
  systemLog("usedp", "UPDATUJI: ", providerId, ", data: ", val);
2217
- dispatch("updateDataStore", { id: providerId, data: val });
2591
+ dispatch("updateDataStore", { id: runtimeProviderRef.runtimeId, data: val });
2218
2592
  };
2219
2593
  const updateItem = ({ params, data: data2, variant, documentId = void 0 }, callback) => {
2220
- dispatch("updateDataStore", { id: providerId, variant, params, data: data2, documentId }, callback);
2594
+ dispatch("updateDataStore", { id: runtimeProviderRef.runtimeId, variant, params, data: data2, documentId }, callback);
2221
2595
  };
2222
2596
  const deleteItem = ({ params, data: data2 }, callback) => {
2223
- dispatch("deleteProviderItem", { providerId, data: data2, params }, callback);
2597
+ dispatch("deleteProviderItem", { providerId: runtimeProviderRef.runtimeId, data: data2, params }, callback);
2224
2598
  };
2225
2599
  const createItem = ({
2226
2600
  data: data2,
@@ -2228,16 +2602,16 @@ var useProviderActions = (providerId, data) => {
2228
2602
  callback
2229
2603
  }) => {
2230
2604
  systemLog("usedp", "createItem Prov. id:", providerId);
2231
- return new Promise((resolve, reject) => {
2605
+ return new Promise((resolve) => {
2232
2606
  const wrappedCallback = (result) => {
2233
2607
  callback?.(result);
2234
2608
  resolve(result);
2235
2609
  };
2236
- dispatch("createProviderItem", { id: providerId, data: data2, variant }, wrappedCallback);
2610
+ dispatch("createProviderItem", { id: runtimeProviderRef.runtimeId, data: data2, variant }, wrappedCallback);
2237
2611
  });
2238
2612
  };
2239
2613
  return {
2240
- schema: providers[providerId]?.schema,
2614
+ schema: providers[runtimeProviderRef.runtimeId]?.schema,
2241
2615
  update,
2242
2616
  updateItem,
2243
2617
  deleteItem,