@mgarlik/datastore 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React$1, { ReactNode } from 'react';
2
2
  import { D as DataStoreStorage } from './storage-D_xv8gFb.cjs';
3
3
 
4
4
  type ProviderDataSourceType = {
@@ -59,6 +59,27 @@ type ProviderEditorType = {
59
59
  };
60
60
  };
61
61
 
62
+ type ProviderLayoutType = {
63
+ title?: string;
64
+ variant?: "grouped" | "insetGrouped" | "plain";
65
+ tooltip?: string | React.ReactNode;
66
+ sections?: {
67
+ id: string;
68
+ title?: string;
69
+ description?: string;
70
+ footer?: string;
71
+ tooltip?: string | React.ReactNode;
72
+ visible?: boolean | JsonFilter;
73
+ items: Array<{
74
+ field: string;
75
+ form?: "textInput" | "select" | "switch" | "dateTime";
76
+ label?: string; // jen override
77
+ visible?: boolean | JsonFilter;
78
+ tooltip?: string | React.ReactNode;
79
+ }>;
80
+ }[];
81
+ };
82
+
62
83
  type ProviderSchemaItemType = {
63
84
  /**
64
85
  * Zdrojove pole pro hodnotu (např. "name" nebo "price"). Pokud není uvedeno, očekává se, že hodnota bude přímo v kořenovém objektu.
@@ -90,8 +111,12 @@ type ProviderSchemaItemType = {
90
111
  mode?: "screen";
91
112
  title?: string;
92
113
  placeholder?: string;
93
- dataSource?: { dataProvider: ProviderTypes };
94
- itemRules?: string;
114
+ // Pro select a radio
115
+ options?: { value: any; label?: string, icon?: string }[] | {
116
+ dataProvider: ProviderTypes;
117
+ optionKeys?: { value: string; label: LabelProps | { title: string; icon: string } };
118
+ filter?: string | RuleType;
119
+ };
95
120
  description?: string;
96
121
  /** TODO: Divna definice labelu */
97
122
  optionKeys?: { value: string; label: LabelProps | { title: string; icon: string } };
@@ -124,6 +149,7 @@ type DataProviderType = {
124
149
  autoCreate?: boolean;
125
150
  schema?: { [key: string]: ProviderSchemaItemType };
126
151
  editor?: ProviderEditorType;
152
+ layout?: ProviderLayoutType;
127
153
  /**
128
154
  * Jake akce jsou povolene pro dataSource. Pokud neni uvedeno, jsou povolene vsechny
129
155
  */
@@ -131,12 +157,12 @@ type DataProviderType = {
131
157
  actions?: DataProviderActionType[]; //
132
158
  };
133
159
 
134
- type DataProvidersType = Record<string, DataProviderType>;
160
+ type DataProvidersType = { [key: string]: DataProviderType };
135
161
 
136
162
  /** Kanonický UUID řetězec používaný pro dokumenty a providery. */
137
163
  type Uuid = string;
138
164
  /** JSON-kompatibilní hodnota používaná v payloadu, filtrech a update operacích. */
139
- type JSONType = string | number | boolean | {
165
+ type JSONType = string | number | boolean | null | {
140
166
  [x: string]: JSONType;
141
167
  } | Array<JSONType>;
142
168
  /** Konfigurace Socket.IO serveru používaná DataStoreProviderem. */
@@ -257,15 +283,15 @@ type DataStoreStableType = {
257
283
  getExternalProviders: () => Record<string, any>;
258
284
  };
259
285
  /** Meta informace (isLive, isSynchronizing, sockets, čítače). */
260
- declare const DataStoreContext: React.Context<DataStoreMetaType>;
286
+ declare const DataStoreContext: React$1.Context<DataStoreMetaType>;
261
287
  /** Surová mapa dokumentů */
262
- declare const DataStoreDocumentsContext: React.Context<Record<string, any>>;
288
+ declare const DataStoreDocumentsContext: React$1.Context<Record<string, any>>;
263
289
  /** Surová mapa providerů */
264
- declare const DataStoreProvidersContext: React.Context<Record<string, any>>;
290
+ declare const DataStoreProvidersContext: React$1.Context<Record<string, any>>;
265
291
  /** Stabilní action callbacky */
266
- declare const DataStoreActionsContext: React.Context<DataStoreActionsType>;
292
+ declare const DataStoreActionsContext: React$1.Context<DataStoreActionsType>;
267
293
  /** Stabilní datastore API pro provider-scoped subscriptions */
268
- declare const DataStoreStableContext: React.Context<DataStoreStableType>;
294
+ declare const DataStoreStableContext: React$1.Context<DataStoreStableType>;
269
295
  /** Vrací všechny stabilní action callbacky. Komponenty s tímto hookem se nepřerenderují při změnách dokumentů. */
270
296
  declare const useDataStoreActions: () => DataStoreActionsType;
271
297
  /**
@@ -279,7 +305,7 @@ declare const useDataStoreActions: () => DataStoreActionsType;
279
305
  */
280
306
  declare const useFilteredDocuments: (filter: Record<string, any>) => {
281
307
  documents: any[] | Record<string, any>;
282
- setFilter: React.Dispatch<React.SetStateAction<Record<string, any>>>;
308
+ setFilter: React$1.Dispatch<React$1.SetStateAction<Record<string, any>>>;
283
309
  };
284
310
  /**
285
311
  * Vrati objekt vsech dokumentu
@@ -340,13 +366,14 @@ type DataStoreRef = DataStoreActionsType;
340
366
  * Podporuje volitelný `ref` (`DataStoreRef`) pro imperativní přístup k akcím
341
367
  * přímo z rodičovské komponenty bez použití kontextového hooku.
342
368
  */
343
- declare const DataStoreProvider: React.ForwardRefExoticComponent<DataStoreProps & React.RefAttributes<DataStoreActionsType>>;
369
+ declare const DataStoreProvider: React$1.ForwardRefExoticComponent<DataStoreProps & React$1.RefAttributes<DataStoreActionsType>>;
344
370
 
345
371
  interface UseDataProviderResult {
346
372
  /** Materializované dokumenty providera po vyhodnocení šablon a filtraci. */
347
373
  documents: Array<Record<string, any>>;
348
374
  /** Schéma providera, pokud je dostupné. */
349
375
  schema?: Record<string, any>;
376
+ layout?: ProviderLayoutType;
350
377
  /** Aktualizuje data providera pomocí výchozí update varianty. */
351
378
  update: (val: JSONType) => void;
352
379
  /** Aktualizuje položku/položky providera s volitelnou variantou a route parametry. */
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React$1, { ReactNode } from 'react';
2
2
  import { D as DataStoreStorage } from './storage-D_xv8gFb.js';
3
3
 
4
4
  type ProviderDataSourceType = {
@@ -59,6 +59,27 @@ type ProviderEditorType = {
59
59
  };
60
60
  };
61
61
 
62
+ type ProviderLayoutType = {
63
+ title?: string;
64
+ variant?: "grouped" | "insetGrouped" | "plain";
65
+ tooltip?: string | React.ReactNode;
66
+ sections?: {
67
+ id: string;
68
+ title?: string;
69
+ description?: string;
70
+ footer?: string;
71
+ tooltip?: string | React.ReactNode;
72
+ visible?: boolean | JsonFilter;
73
+ items: Array<{
74
+ field: string;
75
+ form?: "textInput" | "select" | "switch" | "dateTime";
76
+ label?: string; // jen override
77
+ visible?: boolean | JsonFilter;
78
+ tooltip?: string | React.ReactNode;
79
+ }>;
80
+ }[];
81
+ };
82
+
62
83
  type ProviderSchemaItemType = {
63
84
  /**
64
85
  * Zdrojove pole pro hodnotu (např. "name" nebo "price"). Pokud není uvedeno, očekává se, že hodnota bude přímo v kořenovém objektu.
@@ -90,8 +111,12 @@ type ProviderSchemaItemType = {
90
111
  mode?: "screen";
91
112
  title?: string;
92
113
  placeholder?: string;
93
- dataSource?: { dataProvider: ProviderTypes };
94
- itemRules?: string;
114
+ // Pro select a radio
115
+ options?: { value: any; label?: string, icon?: string }[] | {
116
+ dataProvider: ProviderTypes;
117
+ optionKeys?: { value: string; label: LabelProps | { title: string; icon: string } };
118
+ filter?: string | RuleType;
119
+ };
95
120
  description?: string;
96
121
  /** TODO: Divna definice labelu */
97
122
  optionKeys?: { value: string; label: LabelProps | { title: string; icon: string } };
@@ -124,6 +149,7 @@ type DataProviderType = {
124
149
  autoCreate?: boolean;
125
150
  schema?: { [key: string]: ProviderSchemaItemType };
126
151
  editor?: ProviderEditorType;
152
+ layout?: ProviderLayoutType;
127
153
  /**
128
154
  * Jake akce jsou povolene pro dataSource. Pokud neni uvedeno, jsou povolene vsechny
129
155
  */
@@ -131,12 +157,12 @@ type DataProviderType = {
131
157
  actions?: DataProviderActionType[]; //
132
158
  };
133
159
 
134
- type DataProvidersType = Record<string, DataProviderType>;
160
+ type DataProvidersType = { [key: string]: DataProviderType };
135
161
 
136
162
  /** Kanonický UUID řetězec používaný pro dokumenty a providery. */
137
163
  type Uuid = string;
138
164
  /** JSON-kompatibilní hodnota používaná v payloadu, filtrech a update operacích. */
139
- type JSONType = string | number | boolean | {
165
+ type JSONType = string | number | boolean | null | {
140
166
  [x: string]: JSONType;
141
167
  } | Array<JSONType>;
142
168
  /** Konfigurace Socket.IO serveru používaná DataStoreProviderem. */
@@ -257,15 +283,15 @@ type DataStoreStableType = {
257
283
  getExternalProviders: () => Record<string, any>;
258
284
  };
259
285
  /** Meta informace (isLive, isSynchronizing, sockets, čítače). */
260
- declare const DataStoreContext: React.Context<DataStoreMetaType>;
286
+ declare const DataStoreContext: React$1.Context<DataStoreMetaType>;
261
287
  /** Surová mapa dokumentů */
262
- declare const DataStoreDocumentsContext: React.Context<Record<string, any>>;
288
+ declare const DataStoreDocumentsContext: React$1.Context<Record<string, any>>;
263
289
  /** Surová mapa providerů */
264
- declare const DataStoreProvidersContext: React.Context<Record<string, any>>;
290
+ declare const DataStoreProvidersContext: React$1.Context<Record<string, any>>;
265
291
  /** Stabilní action callbacky */
266
- declare const DataStoreActionsContext: React.Context<DataStoreActionsType>;
292
+ declare const DataStoreActionsContext: React$1.Context<DataStoreActionsType>;
267
293
  /** Stabilní datastore API pro provider-scoped subscriptions */
268
- declare const DataStoreStableContext: React.Context<DataStoreStableType>;
294
+ declare const DataStoreStableContext: React$1.Context<DataStoreStableType>;
269
295
  /** Vrací všechny stabilní action callbacky. Komponenty s tímto hookem se nepřerenderují při změnách dokumentů. */
270
296
  declare const useDataStoreActions: () => DataStoreActionsType;
271
297
  /**
@@ -279,7 +305,7 @@ declare const useDataStoreActions: () => DataStoreActionsType;
279
305
  */
280
306
  declare const useFilteredDocuments: (filter: Record<string, any>) => {
281
307
  documents: any[] | Record<string, any>;
282
- setFilter: React.Dispatch<React.SetStateAction<Record<string, any>>>;
308
+ setFilter: React$1.Dispatch<React$1.SetStateAction<Record<string, any>>>;
283
309
  };
284
310
  /**
285
311
  * Vrati objekt vsech dokumentu
@@ -340,13 +366,14 @@ type DataStoreRef = DataStoreActionsType;
340
366
  * Podporuje volitelný `ref` (`DataStoreRef`) pro imperativní přístup k akcím
341
367
  * přímo z rodičovské komponenty bez použití kontextového hooku.
342
368
  */
343
- declare const DataStoreProvider: React.ForwardRefExoticComponent<DataStoreProps & React.RefAttributes<DataStoreActionsType>>;
369
+ declare const DataStoreProvider: React$1.ForwardRefExoticComponent<DataStoreProps & React$1.RefAttributes<DataStoreActionsType>>;
344
370
 
345
371
  interface UseDataProviderResult {
346
372
  /** Materializované dokumenty providera po vyhodnocení šablon a filtraci. */
347
373
  documents: Array<Record<string, any>>;
348
374
  /** Schéma providera, pokud je dostupné. */
349
375
  schema?: Record<string, any>;
376
+ layout?: ProviderLayoutType;
350
377
  /** Aktualizuje data providera pomocí výchozí update varianty. */
351
378
  update: (val: JSONType) => void;
352
379
  /** Aktualizuje položku/položky providera s volitelnou variantou a route parametry. */
package/dist/index.js CHANGED
@@ -1997,6 +1997,79 @@ var DataStoreProvider_default = DataStoreProvider;
1997
1997
 
1998
1998
  // src/useDataProvider.tsx
1999
1999
  import { useCallback as useCallback2, useContext as useContext2, useEffect as useEffect2, useMemo as useMemo2, useState as useState2, useSyncExternalStore } from "react";
2000
+ var getDynamicOptionsConfig = (schema) => {
2001
+ if (!schema) return [];
2002
+ const configs = [];
2003
+ Object.entries(schema).forEach(([fieldKey, schemaItem]) => {
2004
+ if (!schemaItem || typeof schemaItem !== "object") return;
2005
+ if (schemaItem.options && !Array.isArray(schemaItem.options) && typeof schemaItem.options === "object" && schemaItem.options.dataProvider) {
2006
+ configs.push({
2007
+ fieldKey,
2008
+ dataProvider: schemaItem.options.dataProvider,
2009
+ optionKeys: schemaItem.options.optionKeys,
2010
+ filter: schemaItem.options.filter
2011
+ });
2012
+ return;
2013
+ }
2014
+ if (schemaItem.dataSource?.dataProvider) {
2015
+ configs.push({
2016
+ fieldKey,
2017
+ dataProvider: schemaItem.dataSource.dataProvider,
2018
+ optionKeys: schemaItem.optionKeys,
2019
+ filter: schemaItem.filter
2020
+ });
2021
+ }
2022
+ });
2023
+ return configs;
2024
+ };
2025
+ var resolveProviderRef = (providerId, providers, presetProviders, params) => {
2026
+ if (providers[providerId]) {
2027
+ return {
2028
+ templateId: providerId,
2029
+ runtimeId: providerId
2030
+ };
2031
+ }
2032
+ if (presetProviders[providerId]) {
2033
+ const renderedProvider = renderJSONTemplate(presetProviders[providerId], params ?? void 0);
2034
+ return {
2035
+ templateId: providerId,
2036
+ runtimeId: renderedProvider.id
2037
+ };
2038
+ }
2039
+ return {
2040
+ templateId: providerId,
2041
+ runtimeId: providerId
2042
+ };
2043
+ };
2044
+ var createOptionFromDocument = (doc, optionKeys) => {
2045
+ const valuePath = optionKeys?.value || "id";
2046
+ const optionValue = getValueByDotPath(doc, valuePath, doc.id);
2047
+ const labelDefinition = optionKeys?.label;
2048
+ let optionLabel = "";
2049
+ let optionIcon;
2050
+ if (typeof labelDefinition === "string") {
2051
+ optionLabel = String(getValueByDotPath(doc, labelDefinition, optionValue ?? ""));
2052
+ } else if (labelDefinition && typeof labelDefinition === "object") {
2053
+ const labelPath = labelDefinition.title || "name";
2054
+ optionLabel = String(getValueByDotPath(doc, labelPath, optionValue ?? ""));
2055
+ if (labelDefinition.icon) {
2056
+ optionIcon = getValueByDotPath(doc, labelDefinition.icon);
2057
+ }
2058
+ } else {
2059
+ optionLabel = String(optionValue ?? "");
2060
+ }
2061
+ if (optionIcon) {
2062
+ return {
2063
+ value: optionValue,
2064
+ label: optionLabel,
2065
+ icon: optionIcon
2066
+ };
2067
+ }
2068
+ return {
2069
+ value: optionValue,
2070
+ label: optionLabel
2071
+ };
2072
+ };
2000
2073
  var useDataProvider = (id, params, dataFilter, settings) => {
2001
2074
  const [providerId, setProviderId] = useState2(null);
2002
2075
  const [filter, setFilter] = useState2(null);
@@ -2024,6 +2097,37 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2024
2097
  }, [providerId, getProviderLastUpdate]),
2025
2098
  () => null
2026
2099
  );
2100
+ const dependentProviders = useMemo2(() => {
2101
+ const providers = getExternalProviders();
2102
+ if (!providerId || !providers[providerId]?.schema) return [];
2103
+ const schema = providers[providerId]?.schema;
2104
+ const optionConfigs = getDynamicOptionsConfig(schema);
2105
+ const uniqueProviders = {};
2106
+ optionConfigs.forEach((cfg) => {
2107
+ const resolved = resolveProviderRef(cfg.dataProvider, providers, presetProviders, params);
2108
+ if (resolved.runtimeId === providerId) return;
2109
+ uniqueProviders[resolved.runtimeId] = resolved;
2110
+ });
2111
+ return Object.values(uniqueProviders);
2112
+ }, [providerId, providerVersion, getExternalProviders, presetProviders, params]);
2113
+ const dependentProviderVersion = useSyncExternalStore(
2114
+ useCallback2(
2115
+ (onStoreChange) => {
2116
+ if (dependentProviders.length === 0) return () => {
2117
+ };
2118
+ const unsubscribers = dependentProviders.map((providerRef) => subscribeToProvider(providerRef.runtimeId, onStoreChange));
2119
+ return () => {
2120
+ unsubscribers.forEach((unsubscribe) => unsubscribe?.());
2121
+ };
2122
+ },
2123
+ [dependentProviders, subscribeToProvider]
2124
+ ),
2125
+ useCallback2(() => {
2126
+ if (dependentProviders.length === 0) return "";
2127
+ return dependentProviders.map((providerRef) => String(getProviderLastUpdate(providerRef.runtimeId) ?? "")).join("|");
2128
+ }, [dependentProviders, getProviderLastUpdate]),
2129
+ () => ""
2130
+ );
2027
2131
  systemLog("usedp", `${id} - ${providerId}`);
2028
2132
  useEffect2(() => {
2029
2133
  if (id === void 0 || typeof id === "boolean" && id === false) return;
@@ -2063,6 +2167,45 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2063
2167
  }
2064
2168
  };
2065
2169
  }, []);
2170
+ useEffect2(() => {
2171
+ if (dependentProviders.length === 0) return;
2172
+ const currentProviders = getExternalProviders();
2173
+ const incrementedProviders = [];
2174
+ const createdProviders = [];
2175
+ dependentProviders.forEach((providerRef) => {
2176
+ if (providerRef.runtimeId === providerId) return;
2177
+ if (currentProviders[providerRef.runtimeId]) {
2178
+ if (!currentProviders[providerRef.runtimeId]?.isPermanent) {
2179
+ updateProviderListeners(providerRef.runtimeId, 1);
2180
+ incrementedProviders.push(providerRef.runtimeId);
2181
+ }
2182
+ return;
2183
+ }
2184
+ if (!presetProviders[providerRef.templateId]) {
2185
+ systemLog("usedp", "Neznamy provider v schema.options", providerRef.templateId);
2186
+ return;
2187
+ }
2188
+ const renderedProvider = renderJSONTemplate(presetProviders[providerRef.templateId], params ?? void 0);
2189
+ dispatch("registerProvider", renderedProvider);
2190
+ createdProviders.push({
2191
+ templateId: providerRef.templateId,
2192
+ runtimeId: renderedProvider.id
2193
+ });
2194
+ });
2195
+ return () => {
2196
+ incrementedProviders.forEach((id2) => {
2197
+ updateProviderListeners(id2, -1);
2198
+ });
2199
+ if (createdProviders.length === 0) return;
2200
+ const activeProviders = getExternalProviders();
2201
+ createdProviders.forEach((providerRef) => {
2202
+ const presetProvider = presetProviders[providerRef.templateId];
2203
+ if (!presetProvider?.isPermanent && !activeProviders[providerRef.runtimeId]?.isPermanent) {
2204
+ dispatch("unregisterProvider", providerRef.runtimeId);
2205
+ }
2206
+ });
2207
+ };
2208
+ }, [dependentProviders, providerId, getExternalProviders, updateProviderListeners, dispatch, presetProviders, params]);
2066
2209
  const update = (val) => {
2067
2210
  systemLog("usedp", "UPDATUJI: ", providerId, ", data: ", val);
2068
2211
  dispatch("updateDataStore", { id: providerId, data: val });
@@ -2115,16 +2258,61 @@ var useDataProvider = (id, params, dataFilter, settings) => {
2115
2258
  docs = filterDocuments(docs, filter);
2116
2259
  systemLog("usedp", "Konec filteru: ");
2117
2260
  }
2261
+ const schema = providers[providerId].schema;
2262
+ let resolvedSchema = schema;
2263
+ if (schema) {
2264
+ const optionConfigs = getDynamicOptionsConfig(schema);
2265
+ if (optionConfigs.length > 0) {
2266
+ resolvedSchema = { ...schema };
2267
+ optionConfigs.forEach((cfg) => {
2268
+ const providerRef = resolveProviderRef(cfg.dataProvider, providers, presetProviders, params);
2269
+ const optionProvider = providers[providerRef.runtimeId];
2270
+ if (!optionProvider) {
2271
+ systemLog("usedp", "Nenalezen provider pro schema.options", cfg.dataProvider);
2272
+ return;
2273
+ }
2274
+ let optionDocuments = (optionProvider.data || []).map((docId) => {
2275
+ const docData = documents[docId];
2276
+ if (!docData) return null;
2277
+ return {
2278
+ id: docId,
2279
+ ...docData
2280
+ };
2281
+ }).filter((item) => !!item);
2282
+ if (cfg.filter) {
2283
+ optionDocuments = filterDocuments(optionDocuments, cfg.filter);
2284
+ }
2285
+ const computedOptions = optionDocuments.map((item) => createOptionFromDocument(item, cfg.optionKeys));
2286
+ const nextItem = {
2287
+ ...resolvedSchema[cfg.fieldKey],
2288
+ options: computedOptions
2289
+ };
2290
+ resolvedSchema[cfg.fieldKey] = nextItem;
2291
+ });
2292
+ }
2293
+ }
2118
2294
  return {
2119
2295
  ...providers[providerId],
2120
- data: docs
2296
+ data: docs,
2297
+ schema: resolvedSchema
2121
2298
  };
2122
- }, [providerId, providerVersion, settings?.document, settings?.documentId, getExternalProviders, getExternalDocuments]);
2299
+ }, [
2300
+ providerId,
2301
+ providerVersion,
2302
+ dependentProviderVersion,
2303
+ settings?.document,
2304
+ settings?.documentId,
2305
+ getExternalProviders,
2306
+ getExternalDocuments,
2307
+ presetProviders,
2308
+ params
2309
+ ]);
2123
2310
  systemLog("usedp", `${providerId} END`);
2124
2311
  return {
2125
2312
  // provider,
2126
2313
  documents: provider.data,
2127
2314
  schema: provider.schema,
2315
+ layout: provider.layout,
2128
2316
  // dispatch,
2129
2317
  update,
2130
2318
  updateItem,