@ramme-io/kernel 1.3.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/.turbo/turbo-build.log +5 -0
- package/LICENSE +21 -0
- package/dist/components/AutoForm.d.ts +24 -0
- package/dist/components/AutoForm.d.ts.map +1 -0
- package/dist/components/AutoForm.js +78 -0
- package/dist/components/AutoForm.js.map +1 -0
- package/dist/components/SmartTable.d.ts +14 -0
- package/dist/components/SmartTable.d.ts.map +1 -0
- package/dist/components/SmartTable.js +128 -0
- package/dist/components/SmartTable.js.map +1 -0
- package/dist/config/app.manifest.d.ts +7 -0
- package/dist/config/app.manifest.d.ts.map +1 -0
- package/dist/config/app.manifest.js +8 -0
- package/dist/config/app.manifest.js.map +1 -0
- package/dist/engine/renderers/DynamicBlock.d.ts +9 -0
- package/dist/engine/renderers/DynamicBlock.d.ts.map +1 -0
- package/dist/engine/renderers/DynamicBlock.js +67 -0
- package/dist/engine/renderers/DynamicBlock.js.map +1 -0
- package/dist/engine/renderers/DynamicPage.d.ts +11 -0
- package/dist/engine/renderers/DynamicPage.d.ts.map +1 -0
- package/dist/engine/renderers/DynamicPage.js +91 -0
- package/dist/engine/renderers/DynamicPage.js.map +1 -0
- package/dist/engine/renderers/route-generator.d.ts +16 -0
- package/dist/engine/renderers/route-generator.d.ts.map +1 -0
- package/dist/engine/renderers/route-generator.js +30 -0
- package/dist/engine/renderers/route-generator.js.map +1 -0
- package/dist/engine/renderers/sitemap-entry.d.ts +7 -0
- package/dist/engine/renderers/sitemap-entry.d.ts.map +1 -0
- package/dist/engine/renderers/sitemap-entry.js +2 -0
- package/dist/engine/renderers/sitemap-entry.js.map +1 -0
- package/dist/engine/runtime/ManifestContext.d.ts +115 -0
- package/dist/engine/runtime/ManifestContext.d.ts.map +1 -0
- package/dist/engine/runtime/ManifestContext.js +56 -0
- package/dist/engine/runtime/ManifestContext.js.map +1 -0
- package/dist/engine/runtime/MqttContext.d.ts +14 -0
- package/dist/engine/runtime/MqttContext.d.ts.map +1 -0
- package/dist/engine/runtime/MqttContext.js +70 -0
- package/dist/engine/runtime/MqttContext.js.map +1 -0
- package/dist/engine/runtime/SitemapContext.d.ts +31 -0
- package/dist/engine/runtime/SitemapContext.d.ts.map +1 -0
- package/dist/engine/runtime/SitemapContext.js +54 -0
- package/dist/engine/runtime/SitemapContext.js.map +1 -0
- package/dist/engine/runtime/data-seeder.d.ts +10 -0
- package/dist/engine/runtime/data-seeder.d.ts.map +1 -0
- package/dist/engine/runtime/data-seeder.js +35 -0
- package/dist/engine/runtime/data-seeder.js.map +1 -0
- package/dist/engine/runtime/useAction.d.ts +4 -0
- package/dist/engine/runtime/useAction.d.ts.map +1 -0
- package/dist/engine/runtime/useAction.js +55 -0
- package/dist/engine/runtime/useAction.js.map +1 -0
- package/dist/engine/runtime/useCrudLocalStorage.d.ts +19 -0
- package/dist/engine/runtime/useCrudLocalStorage.d.ts.map +1 -0
- package/dist/engine/runtime/useCrudLocalStorage.js +73 -0
- package/dist/engine/runtime/useCrudLocalStorage.js.map +1 -0
- package/dist/engine/runtime/useDataQuery.d.ts +39 -0
- package/dist/engine/runtime/useDataQuery.d.ts.map +1 -0
- package/dist/engine/runtime/useDataQuery.js +50 -0
- package/dist/engine/runtime/useDataQuery.js.map +1 -0
- package/dist/engine/runtime/useDynamicSitemap.d.ts +9 -0
- package/dist/engine/runtime/useDynamicSitemap.d.ts.map +1 -0
- package/dist/engine/runtime/useDynamicSitemap.js +38 -0
- package/dist/engine/runtime/useDynamicSitemap.js.map +1 -0
- package/dist/engine/runtime/useJustInTimeSeeder.d.ts +11 -0
- package/dist/engine/runtime/useJustInTimeSeeder.d.ts.map +1 -0
- package/dist/engine/runtime/useJustInTimeSeeder.js +88 -0
- package/dist/engine/runtime/useJustInTimeSeeder.js.map +1 -0
- package/dist/engine/runtime/useLiveBridge.d.ts +109 -0
- package/dist/engine/runtime/useLiveBridge.d.ts.map +1 -0
- package/dist/engine/runtime/useLiveBridge.js +21 -0
- package/dist/engine/runtime/useLiveBridge.js.map +1 -0
- package/dist/engine/runtime/useSignal.d.ts +11 -0
- package/dist/engine/runtime/useSignal.d.ts.map +1 -0
- package/dist/engine/runtime/useSignal.js +26 -0
- package/dist/engine/runtime/useSignal.js.map +1 -0
- package/dist/engine/runtime/useSignalStore.d.ts +31 -0
- package/dist/engine/runtime/useSignalStore.d.ts.map +1 -0
- package/dist/engine/runtime/useSignalStore.js +60 -0
- package/dist/engine/runtime/useSignalStore.js.map +1 -0
- package/dist/engine/runtime/useWorkflowEngine.d.ts +4 -0
- package/dist/engine/runtime/useWorkflowEngine.d.ts.map +1 -0
- package/dist/engine/runtime/useWorkflowEngine.js +85 -0
- package/dist/engine/runtime/useWorkflowEngine.js.map +1 -0
- package/dist/engine/types/manifest-types.d.ts +38 -0
- package/dist/engine/types/manifest-types.d.ts.map +1 -0
- package/dist/engine/types/manifest-types.js +5 -0
- package/dist/engine/types/manifest-types.js.map +1 -0
- package/dist/engine/types/sitemap-entry.d.ts +58 -0
- package/dist/engine/types/sitemap-entry.d.ts.map +1 -0
- package/dist/engine/types/sitemap-entry.js +19 -0
- package/dist/engine/types/sitemap-entry.js.map +1 -0
- package/dist/engine/validation/schema.d.ts +383 -0
- package/dist/engine/validation/schema.d.ts.map +1 -0
- package/dist/engine/validation/schema.js +156 -0
- package/dist/engine/validation/schema.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/package.json +36 -0
- package/src/components/AutoForm.tsx +141 -0
- package/src/components/SmartTable.tsx +316 -0
- package/src/config/app.manifest.ts +7 -0
- package/src/engine/renderers/DynamicBlock.tsx +84 -0
- package/src/engine/renderers/DynamicPage.tsx +196 -0
- package/src/engine/renderers/route-generator.tsx +47 -0
- package/src/engine/renderers/sitemap-entry.ts +6 -0
- package/src/engine/runtime/ManifestContext.tsx +81 -0
- package/src/engine/runtime/MqttContext.tsx +94 -0
- package/src/engine/runtime/SitemapContext.tsx +61 -0
- package/src/engine/runtime/data-seeder.ts +39 -0
- package/src/engine/runtime/useAction.ts +64 -0
- package/src/engine/runtime/useCrudLocalStorage.ts +82 -0
- package/src/engine/runtime/useDataQuery.ts +98 -0
- package/src/engine/runtime/useDynamicSitemap.tsx +43 -0
- package/src/engine/runtime/useJustInTimeSeeder.ts +101 -0
- package/src/engine/runtime/useLiveBridge.ts +24 -0
- package/src/engine/runtime/useSignal.ts +40 -0
- package/src/engine/runtime/useSignalStore.ts +94 -0
- package/src/engine/runtime/useWorkflowEngine.ts +89 -0
- package/src/engine/types/manifest-types.ts +45 -0
- package/src/engine/types/sitemap-entry.ts +66 -0
- package/src/engine/validation/schema.ts +189 -0
- package/src/index.ts +27 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file useDataQuery.ts
|
|
3
|
+
* @description The "In-Memory Database Engine".
|
|
4
|
+
*
|
|
5
|
+
* ARCHITECTURAL ROLE:
|
|
6
|
+
* Since this application runs without a real backend, this hook acts as the
|
|
7
|
+
* SQL Query Engine. It takes raw arrays from the Data Lake and performs
|
|
8
|
+
* real-time filtering, sorting, and pagination before passing the result
|
|
9
|
+
* to the UI.
|
|
10
|
+
*
|
|
11
|
+
* CAPABILITIES:
|
|
12
|
+
* 1. WHERE: Supports complex filtering (equals, contains, gt, lt).
|
|
13
|
+
* 2. ORDER BY: Handles ascending/descending sorts on any field.
|
|
14
|
+
* 3. LIMIT/OFFSET: Calculates pagination slices automatically.
|
|
15
|
+
*/
|
|
16
|
+
export type SortDirection = 'asc' | 'desc';
|
|
17
|
+
export interface SortOption {
|
|
18
|
+
field: string;
|
|
19
|
+
direction: SortDirection;
|
|
20
|
+
}
|
|
21
|
+
export interface FilterOption {
|
|
22
|
+
field: string;
|
|
23
|
+
operator: 'equals' | 'contains' | 'gt' | 'lt' | 'neq';
|
|
24
|
+
value: any;
|
|
25
|
+
}
|
|
26
|
+
export interface QueryOptions {
|
|
27
|
+
filters?: FilterOption[];
|
|
28
|
+
sort?: SortOption;
|
|
29
|
+
page?: number;
|
|
30
|
+
pageSize?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface QueryResult<T> {
|
|
33
|
+
data: T[];
|
|
34
|
+
total: number;
|
|
35
|
+
pageCount: number;
|
|
36
|
+
}
|
|
37
|
+
export declare function useDataQuery<T>(rawData: T[], // <--- Now accepts an Array, NOT a string ID
|
|
38
|
+
options?: QueryOptions): QueryResult<T>;
|
|
39
|
+
//# sourceMappingURL=useDataQuery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDataQuery.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useDataQuery.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IACtD,KAAK,EAAE,GAAG,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,YAAY,CAAC,CAAC,EAC5B,OAAO,EAAE,CAAC,EAAE,EAAE,6CAA6C;AAC3D,OAAO,GAAE,YAAiB,GACzB,WAAW,CAAC,CAAC,CAAC,CAgDhB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
// --- 2. Update the Hook Signature (Fixes ts(2345)) ---
|
|
3
|
+
export function useDataQuery(rawData, // <--- Now accepts an Array, NOT a string ID
|
|
4
|
+
options = {}) {
|
|
5
|
+
const { filters, sort, page = 1, pageSize = 10 } = options;
|
|
6
|
+
// A. Filtering Logic
|
|
7
|
+
const filteredData = useMemo(() => {
|
|
8
|
+
if (!filters || filters.length === 0)
|
|
9
|
+
return rawData;
|
|
10
|
+
return rawData.filter((item) => {
|
|
11
|
+
return filters.every((filter) => {
|
|
12
|
+
const itemValue = item[filter.field];
|
|
13
|
+
switch (filter.operator) {
|
|
14
|
+
case 'equals': return itemValue == filter.value;
|
|
15
|
+
case 'neq': return itemValue != filter.value;
|
|
16
|
+
case 'contains':
|
|
17
|
+
return String(itemValue).toLowerCase().includes(String(filter.value).toLowerCase());
|
|
18
|
+
case 'gt': return itemValue > filter.value;
|
|
19
|
+
case 'lt': return itemValue < filter.value;
|
|
20
|
+
default: return true;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}, [rawData, filters]);
|
|
25
|
+
// B. Sorting Logic
|
|
26
|
+
const sortedData = useMemo(() => {
|
|
27
|
+
if (!sort)
|
|
28
|
+
return filteredData;
|
|
29
|
+
return [...filteredData].sort((a, b) => {
|
|
30
|
+
const aValue = a[sort.field];
|
|
31
|
+
const bValue = b[sort.field];
|
|
32
|
+
if (aValue < bValue)
|
|
33
|
+
return sort.direction === 'asc' ? -1 : 1;
|
|
34
|
+
if (aValue > bValue)
|
|
35
|
+
return sort.direction === 'asc' ? 1 : -1;
|
|
36
|
+
return 0;
|
|
37
|
+
});
|
|
38
|
+
}, [filteredData, sort]);
|
|
39
|
+
// C. Pagination Logic
|
|
40
|
+
const paginatedResult = useMemo(() => {
|
|
41
|
+
const startIndex = (page - 1) * pageSize;
|
|
42
|
+
return sortedData.slice(startIndex, startIndex + pageSize);
|
|
43
|
+
}, [sortedData, page, pageSize]);
|
|
44
|
+
return {
|
|
45
|
+
data: paginatedResult,
|
|
46
|
+
total: filteredData.length,
|
|
47
|
+
pageCount: Math.ceil(filteredData.length / pageSize),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=useDataQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDataQuery.js","sourceRoot":"","sources":["../../../src/engine/runtime/useDataQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type SitemapEntry } from '../types/sitemap-entry';
|
|
2
|
+
/**
|
|
3
|
+
* @hook useDynamicSitemap
|
|
4
|
+
* @description
|
|
5
|
+
* - In 'Static Mode' (npm run dev): Merges dynamic pages with the hardcoded sitemap.
|
|
6
|
+
* - In 'Live Mode' (Builder): REPLACES the sitemap entirely to show only the user's design.
|
|
7
|
+
*/
|
|
8
|
+
export declare const useDynamicSitemap: (staticSitemap: SitemapEntry[]) => SitemapEntry[];
|
|
9
|
+
//# sourceMappingURL=useDynamicSitemap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynamicSitemap.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useDynamicSitemap.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,eAAe,YAAY,EAAE,mBA8B9D,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useManifest, useBridgeStatus } from './ManifestContext';
|
|
4
|
+
import { DynamicPage } from '../renderers/DynamicPage';
|
|
5
|
+
/**
|
|
6
|
+
* @hook useDynamicSitemap
|
|
7
|
+
* @description
|
|
8
|
+
* - In 'Static Mode' (npm run dev): Merges dynamic pages with the hardcoded sitemap.
|
|
9
|
+
* - In 'Live Mode' (Builder): REPLACES the sitemap entirely to show only the user's design.
|
|
10
|
+
*/
|
|
11
|
+
export const useDynamicSitemap = (staticSitemap) => {
|
|
12
|
+
const manifest = useManifest();
|
|
13
|
+
const status = useBridgeStatus();
|
|
14
|
+
const isLive = status === 'live'; // ✅ Detect Live Mode
|
|
15
|
+
return useMemo(() => {
|
|
16
|
+
// 1. Convert Manifest Pages -> Sitemap Entries
|
|
17
|
+
const dynamicEntries = (manifest.pages || []).map((page) => ({
|
|
18
|
+
id: page.id,
|
|
19
|
+
path: page.slug,
|
|
20
|
+
title: page.title,
|
|
21
|
+
icon: page.icon || 'layout',
|
|
22
|
+
component: () => _jsx(DynamicPage, { pageId: page.id })
|
|
23
|
+
}));
|
|
24
|
+
// 2. ✅ OPTIMIZATION: Exclusive Mode
|
|
25
|
+
// If we are connected to the Builder (Live) AND have dynamic content,
|
|
26
|
+
// we drop the static "Showcase" pages.
|
|
27
|
+
// This makes the Kernel feel like a blank slate to the user.
|
|
28
|
+
if (isLive && dynamicEntries.length > 0) {
|
|
29
|
+
// console.log("🚀 [Sitemap] Live Mode Active: Hiding static pages.");
|
|
30
|
+
return dynamicEntries;
|
|
31
|
+
}
|
|
32
|
+
// 3. Static/Hybrid Mode (Keep existing logic for local dev)
|
|
33
|
+
const staticIds = new Set(staticSitemap.map(s => s.id));
|
|
34
|
+
const uniqueDynamic = dynamicEntries.filter(d => !staticIds.has(d.id));
|
|
35
|
+
return [...staticSitemap, ...uniqueDynamic];
|
|
36
|
+
}, [manifest, staticSitemap, isLive]);
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=useDynamicSitemap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynamicSitemap.js","sourceRoot":"","sources":["../../../src/engine/runtime/useDynamicSitemap.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAIvD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,aAA6B,EAAE,EAAE;IACjE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,qBAAqB;IAEvD,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,+CAA+C;QAC/C,MAAM,cAAc,GAAmB,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3E,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAG,IAAI,CAAC,IAAiB,IAAI,QAAQ;YACzC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAC,WAAW,IAAC,MAAM,EAAE,IAAI,CAAC,EAAE,GAAI;SAClD,CAAC,CAAC,CAAC;QAEJ,oCAAoC;QACpC,sEAAsE;QACtE,wCAAwC;QACxC,6DAA6D;QAC7D,IAAI,MAAM,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,sEAAsE;YACtE,OAAO,cAAc,CAAC;QAC1B,CAAC;QAED,4DAA4D;QAC5D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxD,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEvE,OAAO,CAAC,GAAG,aAAa,EAAE,GAAG,aAAa,CAAC,CAAC;IAC9C,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file useJustInTimeSeeder.ts
|
|
3
|
+
* @description Runtime Data Generator for the Preview Engine.
|
|
4
|
+
* * ARCHITECTURAL NOTE:
|
|
5
|
+
* This hook is "Storage Aware." It does not import static files.
|
|
6
|
+
* It checks the 'ramme_db_' keys in localStorage (which were seeded by main.tsx).
|
|
7
|
+
* If data exists, it uses it. If not, it procedurally generates it.
|
|
8
|
+
*/
|
|
9
|
+
import type { ResourceDefinition } from '../validation/schema';
|
|
10
|
+
export declare const useJustInTimeSeeder: (dataId: string, resourceDef?: ResourceDefinition | null) => any[];
|
|
11
|
+
//# sourceMappingURL=useJustInTimeSeeder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useJustInTimeSeeder.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useJustInTimeSeeder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,sBAAsB,CAAC;AAoChF,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,cAAc,kBAAkB,GAAG,IAAI,UAqD1F,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file useJustInTimeSeeder.ts
|
|
3
|
+
* @description Runtime Data Generator for the Preview Engine.
|
|
4
|
+
* * ARCHITECTURAL NOTE:
|
|
5
|
+
* This hook is "Storage Aware." It does not import static files.
|
|
6
|
+
* It checks the 'ramme_db_' keys in localStorage (which were seeded by main.tsx).
|
|
7
|
+
* If data exists, it uses it. If not, it procedurally generates it.
|
|
8
|
+
*/
|
|
9
|
+
import { useMemo } from 'react';
|
|
10
|
+
// Match the prefix defined in data-seeder.ts
|
|
11
|
+
const DB_PREFIX = 'ramme_db_';
|
|
12
|
+
// Helper: Generate a semi-realistic value based on field type
|
|
13
|
+
const generateValue = (field, index) => {
|
|
14
|
+
const i = index + 1;
|
|
15
|
+
const label = field.label || 'Item';
|
|
16
|
+
switch (field.type) {
|
|
17
|
+
case 'text':
|
|
18
|
+
return `${label} ${i}`;
|
|
19
|
+
case 'number':
|
|
20
|
+
return Math.floor(Math.random() * 100) + 1;
|
|
21
|
+
case 'currency':
|
|
22
|
+
return (Math.random() * 1000).toFixed(2);
|
|
23
|
+
case 'boolean':
|
|
24
|
+
return Math.random() > 0.5;
|
|
25
|
+
case 'date':
|
|
26
|
+
const d = new Date();
|
|
27
|
+
d.setDate(d.getDate() - (i * 2));
|
|
28
|
+
return d.toISOString().split('T')[0]; // Simple YYYY-MM-DD
|
|
29
|
+
case 'status':
|
|
30
|
+
return ['Active', 'Pending', 'Inactive', 'Archived'][index % 4];
|
|
31
|
+
case 'email':
|
|
32
|
+
return `user${i}@example.com`;
|
|
33
|
+
case 'image':
|
|
34
|
+
return `https://i.pravatar.cc/150?u=${i}`;
|
|
35
|
+
case 'textarea':
|
|
36
|
+
return `This is a sample description for ${label} ${i}. It contains enough text to test multi-line rendering.`;
|
|
37
|
+
default:
|
|
38
|
+
return `${label}-${i}`;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export const useJustInTimeSeeder = (dataId, resourceDef) => {
|
|
42
|
+
return useMemo(() => {
|
|
43
|
+
if (!dataId)
|
|
44
|
+
return [];
|
|
45
|
+
// 1. Priority: The Data Lake (Static Seed + User Edits)
|
|
46
|
+
// We trust that main.tsx has already seeded the "Golden Copy" from mockData.ts
|
|
47
|
+
// into localStorage. This ensures we see the EXACT same data as the rest of the app.
|
|
48
|
+
if (typeof window !== 'undefined') {
|
|
49
|
+
const storageKey = `${DB_PREFIX}${dataId}`;
|
|
50
|
+
const localData = localStorage.getItem(storageKey);
|
|
51
|
+
if (localData) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(localData);
|
|
54
|
+
// Only return if we actually have rows
|
|
55
|
+
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
console.warn(`[JIT Seeder] Corrupt data in ${storageKey}, falling back to generation.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 2. Fallback: JIT Generation (The "Safety Net")
|
|
65
|
+
// If we have a schema but absolutely zero data in storage, generate it now.
|
|
66
|
+
if (resourceDef) {
|
|
67
|
+
console.log(`🌱 [JIT Seeder] Generating 5 mock records for: ${dataId}`);
|
|
68
|
+
const generatedData = Array.from({ length: 5 }).map((_, idx) => {
|
|
69
|
+
const row = {
|
|
70
|
+
// Generate a robust ID that won't collide with future real IDs
|
|
71
|
+
id: `jit_${dataId}_${idx + 1}`
|
|
72
|
+
};
|
|
73
|
+
resourceDef.fields.forEach(field => {
|
|
74
|
+
if (field.key !== 'id') {
|
|
75
|
+
row[field.key] = generateValue(field, idx);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return row;
|
|
79
|
+
});
|
|
80
|
+
// OPTIONAL: Persist this generated data so it doesn't regenerate on reload?
|
|
81
|
+
// localStorage.setItem(`${DB_PREFIX}${dataId}`, JSON.stringify(generatedData));
|
|
82
|
+
return generatedData;
|
|
83
|
+
}
|
|
84
|
+
// 3. Empty State (No data, no schema)
|
|
85
|
+
return [];
|
|
86
|
+
}, [dataId, resourceDef]);
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=useJustInTimeSeeder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useJustInTimeSeeder.js","sourceRoot":"","sources":["../../../src/engine/runtime/useJustInTimeSeeder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export declare function useLiveBridge(): {
|
|
2
|
+
manifest: {
|
|
3
|
+
meta: {
|
|
4
|
+
name: string;
|
|
5
|
+
version: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
author?: string;
|
|
8
|
+
createdAt?: string;
|
|
9
|
+
};
|
|
10
|
+
config: {
|
|
11
|
+
theme: "light" | "dark" | "system" | "corporate" | "midnight" | "blueprint";
|
|
12
|
+
mockMode: boolean;
|
|
13
|
+
brokerUrl?: string;
|
|
14
|
+
};
|
|
15
|
+
domain: {
|
|
16
|
+
signals: {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
kind: "status" | "sensor" | "actuator" | "setpoint" | "metric" | "kpi";
|
|
20
|
+
source: "mock" | "mqtt" | "http" | "derived" | "local";
|
|
21
|
+
refreshRate: number;
|
|
22
|
+
description?: string;
|
|
23
|
+
topic?: string;
|
|
24
|
+
endpoint?: string;
|
|
25
|
+
jsonPath?: string;
|
|
26
|
+
defaultValue?: any;
|
|
27
|
+
unit?: string;
|
|
28
|
+
min?: number;
|
|
29
|
+
max?: number;
|
|
30
|
+
}[];
|
|
31
|
+
entities: {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
type: string;
|
|
35
|
+
category: string;
|
|
36
|
+
signals: string[];
|
|
37
|
+
description?: string;
|
|
38
|
+
ui?: {
|
|
39
|
+
icon?: string;
|
|
40
|
+
color?: string;
|
|
41
|
+
dashboardComponent?: string;
|
|
42
|
+
};
|
|
43
|
+
}[];
|
|
44
|
+
workflows?: {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
active: boolean;
|
|
48
|
+
trigger: {
|
|
49
|
+
id: string;
|
|
50
|
+
type: "signal_change" | "manual_action" | "schedule" | "webhook";
|
|
51
|
+
config: Record<string, any>;
|
|
52
|
+
};
|
|
53
|
+
actions: {
|
|
54
|
+
id: string;
|
|
55
|
+
type: "update_resource" | "send_notification" | "mqtt_publish" | "api_call" | "navigate" | "agent_task";
|
|
56
|
+
config: Record<string, any>;
|
|
57
|
+
}[];
|
|
58
|
+
}[];
|
|
59
|
+
};
|
|
60
|
+
modules?: string[];
|
|
61
|
+
resources?: {
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
fields: {
|
|
65
|
+
key: string;
|
|
66
|
+
label: string;
|
|
67
|
+
type: "number" | "boolean" | "text" | "currency" | "date" | "status" | "email" | "image" | "textarea";
|
|
68
|
+
required?: boolean;
|
|
69
|
+
description?: string;
|
|
70
|
+
defaultValue?: any;
|
|
71
|
+
}[];
|
|
72
|
+
defaultView?: "table" | "grid" | "list";
|
|
73
|
+
features?: {
|
|
74
|
+
searchable?: boolean;
|
|
75
|
+
creatable?: boolean;
|
|
76
|
+
editable?: boolean;
|
|
77
|
+
deletable?: boolean;
|
|
78
|
+
exportable?: boolean;
|
|
79
|
+
};
|
|
80
|
+
}[];
|
|
81
|
+
pages?: {
|
|
82
|
+
id: string;
|
|
83
|
+
slug: string;
|
|
84
|
+
title: string;
|
|
85
|
+
sections: {
|
|
86
|
+
id: string;
|
|
87
|
+
blocks: {
|
|
88
|
+
id: string;
|
|
89
|
+
type: string;
|
|
90
|
+
props: Record<string, any>;
|
|
91
|
+
layout?: {
|
|
92
|
+
colSpan?: number;
|
|
93
|
+
rowSpan?: number;
|
|
94
|
+
};
|
|
95
|
+
}[];
|
|
96
|
+
title?: string;
|
|
97
|
+
description?: string;
|
|
98
|
+
layout?: {
|
|
99
|
+
columns?: number;
|
|
100
|
+
variant?: "grid" | "stack" | "split";
|
|
101
|
+
};
|
|
102
|
+
}[];
|
|
103
|
+
description?: string;
|
|
104
|
+
icon?: string;
|
|
105
|
+
}[];
|
|
106
|
+
};
|
|
107
|
+
isLive: boolean;
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=useLiveBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLiveBridge.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useLiveBridge.ts"],"names":[],"mappings":"AAMA,wBAAgB,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB5B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import { useMqtt } from './MqttContext';
|
|
3
|
+
const staticManifest = { name: 'loading', version: '0.0.0', capabilities: [], navigation: [] };
|
|
4
|
+
export function useLiveBridge() {
|
|
5
|
+
// 👇 FIX: Cast the initial state to satisfy the compiler
|
|
6
|
+
const [manifest, setManifest] = useState(staticManifest);
|
|
7
|
+
const { lastMessage, isConnected } = useMqtt();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (lastMessage && lastMessage.topic === 'ramme/manifest/update') {
|
|
10
|
+
try {
|
|
11
|
+
const payload = JSON.parse(lastMessage.payload.toString());
|
|
12
|
+
setManifest(payload);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
console.error('Failed to parse manifest update', e);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}, [lastMessage]);
|
|
19
|
+
return { manifest, isLive: isConnected };
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=useLiveBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLiveBridge.js","sourceRoot":"","sources":["../../../src/engine/runtime/useLiveBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AAE/F,MAAM,UAAU,aAAa;IAC3B,yDAAyD;IACzD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,cAA6C,CAAC,CAAC;IAC1G,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,IAAI,WAAW,CAAC,KAAK,KAAK,uBAAuB,EAAE,CAAC;YACjE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC3D,WAAW,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SignalState {
|
|
2
|
+
id: string;
|
|
3
|
+
value: any;
|
|
4
|
+
unit?: string;
|
|
5
|
+
min?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
timestamp?: number;
|
|
8
|
+
status: 'fresh' | 'stale';
|
|
9
|
+
}
|
|
10
|
+
export declare const useSignal: (signalId: string) => SignalState;
|
|
11
|
+
//# sourceMappingURL=useSignal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSignal.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useSignal.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,GAAG,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM,KAAG,WAuB5C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useSignalStore } from './useSignalStore';
|
|
3
|
+
// ❌ REMOVED: import { appManifest } from '../../config/app.manifest';
|
|
4
|
+
// ✅ ADDED: Live Context
|
|
5
|
+
import { useManifest } from './ManifestContext';
|
|
6
|
+
export const useSignal = (signalId) => {
|
|
7
|
+
const signalData = useSignalStore((state) => state.signals[signalId]);
|
|
8
|
+
// ✅ 1. Consume Live Manifest
|
|
9
|
+
const appManifest = useManifest();
|
|
10
|
+
// 2. Get Static Definition from Manifest (Live)
|
|
11
|
+
const signalDef = useMemo(() => {
|
|
12
|
+
return appManifest.domain.signals.find((s) => s.id === signalId);
|
|
13
|
+
}, [signalId, appManifest]); // Re-run if manifest updates
|
|
14
|
+
const value = signalData?.value ?? signalDef?.defaultValue ?? 0;
|
|
15
|
+
const isStale = signalData ? (Date.now() - signalData.timestamp > 10000) : true;
|
|
16
|
+
return {
|
|
17
|
+
id: signalId,
|
|
18
|
+
value: value,
|
|
19
|
+
unit: signalDef?.unit,
|
|
20
|
+
min: signalDef?.min,
|
|
21
|
+
max: signalDef?.max,
|
|
22
|
+
timestamp: signalData?.timestamp,
|
|
23
|
+
status: isStale ? 'stale' : 'fresh'
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=useSignal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSignal.js","sourceRoot":"","sources":["../../../src/engine/runtime/useSignal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,sEAAsE;AACtE,wBAAwB;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYhD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAe,EAAE;IACzD,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEtE,6BAA6B;IAC7B,MAAM,WAAW,GAAG,WAAW,EAAE,CAAC;IAElC,gDAAgD;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7B,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IACnE,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,6BAA6B;IAE1D,MAAM,KAAK,GAAG,UAAU,EAAE,KAAK,IAAI,SAAS,EAAE,YAAY,IAAI,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhF,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,SAAS,EAAE,IAAI;QACrB,GAAG,EAAE,SAAS,EAAE,GAAG;QACnB,GAAG,EAAE,SAAS,EAAE,GAAG;QACnB,SAAS,EAAE,UAAU,EAAE,SAAS;QAChC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;KACpC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file useSignalStore.ts
|
|
3
|
+
* @description The "Short-Term Memory" of the application.
|
|
4
|
+
*
|
|
5
|
+
* ARCHITECTURAL ROLE:
|
|
6
|
+
* This Zustand store holds the instantaneous value of every Signal (IoT sensor).
|
|
7
|
+
* It acts as the buffer between the high-speed data stream (MQTT/Simulation)
|
|
8
|
+
* and the UI components.
|
|
9
|
+
*/
|
|
10
|
+
export interface SignalValue {
|
|
11
|
+
value: any;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
}
|
|
14
|
+
interface SignalStore {
|
|
15
|
+
signals: Record<string, SignalValue>;
|
|
16
|
+
updateSignal: (id: string, value: any) => void;
|
|
17
|
+
updateSignals: (updates: Record<string, any>) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare const useSignalStore: import("zustand").UseBoundStore<import("zustand").StoreApi<SignalStore>>;
|
|
20
|
+
/**
|
|
21
|
+
* Hook to access specific signals in a component.
|
|
22
|
+
* Usage: const signals = useGeneratedSignals();
|
|
23
|
+
*/
|
|
24
|
+
export declare const useGeneratedSignals: () => Record<string, SignalValue>;
|
|
25
|
+
/**
|
|
26
|
+
* A hook that generates fake data for testing when no MQTT broker is connected.
|
|
27
|
+
* You can toggle this on/off via the manifest config.
|
|
28
|
+
*/
|
|
29
|
+
export declare const useSimulation: (isEnabled?: boolean) => void;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=useSignalStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSignalStore.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useSignalStore.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAGH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,GAAG,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAErC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAE/C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACvD;AAUD,eAAO,MAAM,cAAc,0EAiBxB,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,mBAAmB,mCAE/B,CAAC;AAGF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,YAAW,OAAc,SA0BtD,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
// Initial State matches your dashboard IDs to prevent "undefined" errors on load
|
|
4
|
+
const initialState = {
|
|
5
|
+
living_room_ac: { value: 72, timestamp: Date.now() },
|
|
6
|
+
living_room_hum: { value: 45, timestamp: Date.now() },
|
|
7
|
+
server_01: { value: 42, timestamp: Date.now() },
|
|
8
|
+
front_door_lock: { value: 'LOCKED', timestamp: Date.now() }
|
|
9
|
+
};
|
|
10
|
+
export const useSignalStore = create((set) => ({
|
|
11
|
+
signals: initialState,
|
|
12
|
+
updateSignal: (id, value) => set((state) => ({
|
|
13
|
+
signals: {
|
|
14
|
+
...state.signals,
|
|
15
|
+
[id]: { value, timestamp: Date.now() }
|
|
16
|
+
}
|
|
17
|
+
})),
|
|
18
|
+
updateSignals: (updates) => set((state) => {
|
|
19
|
+
const newSignals = { ...state.signals };
|
|
20
|
+
Object.entries(updates).forEach(([id, val]) => {
|
|
21
|
+
newSignals[id] = { value: val, timestamp: Date.now() };
|
|
22
|
+
});
|
|
23
|
+
return { signals: newSignals };
|
|
24
|
+
})
|
|
25
|
+
}));
|
|
26
|
+
/**
|
|
27
|
+
* Hook to access specific signals in a component.
|
|
28
|
+
* Usage: const signals = useGeneratedSignals();
|
|
29
|
+
*/
|
|
30
|
+
export const useGeneratedSignals = () => {
|
|
31
|
+
return useSignalStore((state) => state.signals);
|
|
32
|
+
};
|
|
33
|
+
// --- 2. SIMULATION ENGINE (The Missing Piece) ---
|
|
34
|
+
/**
|
|
35
|
+
* A hook that generates fake data for testing when no MQTT broker is connected.
|
|
36
|
+
* You can toggle this on/off via the manifest config.
|
|
37
|
+
*/
|
|
38
|
+
export const useSimulation = (isEnabled = true) => {
|
|
39
|
+
const { updateSignals } = useSignalStore();
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!isEnabled)
|
|
42
|
+
return;
|
|
43
|
+
console.log("[System] Simulation Mode: ON 🎲");
|
|
44
|
+
const interval = setInterval(() => {
|
|
45
|
+
// Simulate random fluctuations
|
|
46
|
+
const updates = {};
|
|
47
|
+
// Randomize values slightly around a baseline
|
|
48
|
+
updates['living_room_ac'] = Number((72 + (Math.random() * 4 - 2)).toFixed(1));
|
|
49
|
+
updates['living_room_hum'] = Number((45 + (Math.random() * 6 - 3)).toFixed(1));
|
|
50
|
+
updates['server_01'] = Math.floor(Math.random() * 100);
|
|
51
|
+
// Randomly flip the lock status occasionally (1% chance)
|
|
52
|
+
if (Math.random() > 0.99) {
|
|
53
|
+
updates['front_door_lock'] = Math.random() > 0.5 ? 'LOCKED' : 'UNLOCKED';
|
|
54
|
+
}
|
|
55
|
+
updateSignals(updates);
|
|
56
|
+
}, 2000); // Update every 2 seconds
|
|
57
|
+
return () => clearInterval(interval);
|
|
58
|
+
}, [isEnabled, updateSignals]);
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=useSignalStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSignalStore.js","sourceRoot":"","sources":["../../../src/engine/runtime/useSignalStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA0BlC,iFAAiF;AACjF,MAAM,YAAY,GAAG;IACnB,cAAc,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;IACpD,eAAe,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;IACrD,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;IAC/C,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;CAC5D,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC1D,OAAO,EAAE,YAAY;IAErB,YAAY,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3C,OAAO,EAAE;YACP,GAAG,KAAK,CAAC,OAAO;YAChB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;SACvC;KACF,CAAC,CAAC;IAEH,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE;YAC5C,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IACjC,CAAC,CAAC;CACH,CAAC,CAAC,CAAC;AAEJ;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,EAAE;IACtC,OAAO,cAAc,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,mDAAmD;AACnD;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,YAAqB,IAAI,EAAE,EAAE;IACzD,MAAM,EAAE,aAAa,EAAE,GAAG,cAAc,EAAE,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,+BAA+B;YAC/B,MAAM,OAAO,GAAwB,EAAE,CAAC;YAExC,8CAA8C;YAC9C,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9E,OAAO,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/E,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;YAEvD,yDAAyD;YACzD,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC;gBACxB,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;YAC5E,CAAC;YAED,aAAa,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,yBAAyB;QAEnC,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;AACjC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkflowEngine.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useWorkflowEngine.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,iBAAiB;kCAqDI,MAAM;CASvC,CAAC"}
|