@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 @@
|
|
|
1
|
+
{"version":3,"file":"sitemap-entry.d.ts","sourceRoot":"","sources":["../../../src/engine/renderers/sitemap-entry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;IAC/B,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sitemap-entry.js","sourceRoot":"","sources":["../../../src/engine/renderers/sitemap-entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AppSpecification } from '../validation/schema';
|
|
3
|
+
interface ManifestProviderProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
manifest: AppSpecification;
|
|
6
|
+
}
|
|
7
|
+
export declare const ManifestProvider: React.FC<ManifestProviderProps>;
|
|
8
|
+
export declare const useManifest: () => {
|
|
9
|
+
meta: {
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
author?: string;
|
|
14
|
+
createdAt?: string;
|
|
15
|
+
};
|
|
16
|
+
config: {
|
|
17
|
+
theme: "light" | "dark" | "system" | "corporate" | "midnight" | "blueprint";
|
|
18
|
+
mockMode: boolean;
|
|
19
|
+
brokerUrl?: string;
|
|
20
|
+
};
|
|
21
|
+
domain: {
|
|
22
|
+
signals: {
|
|
23
|
+
id: string;
|
|
24
|
+
label: string;
|
|
25
|
+
kind: "status" | "sensor" | "actuator" | "setpoint" | "metric" | "kpi";
|
|
26
|
+
source: "mock" | "mqtt" | "http" | "derived" | "local";
|
|
27
|
+
refreshRate: number;
|
|
28
|
+
description?: string;
|
|
29
|
+
topic?: string;
|
|
30
|
+
endpoint?: string;
|
|
31
|
+
jsonPath?: string;
|
|
32
|
+
defaultValue?: any;
|
|
33
|
+
unit?: string;
|
|
34
|
+
min?: number;
|
|
35
|
+
max?: number;
|
|
36
|
+
}[];
|
|
37
|
+
entities: {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
category: string;
|
|
42
|
+
signals: string[];
|
|
43
|
+
description?: string;
|
|
44
|
+
ui?: {
|
|
45
|
+
icon?: string;
|
|
46
|
+
color?: string;
|
|
47
|
+
dashboardComponent?: string;
|
|
48
|
+
};
|
|
49
|
+
}[];
|
|
50
|
+
workflows?: {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
active: boolean;
|
|
54
|
+
trigger: {
|
|
55
|
+
id: string;
|
|
56
|
+
type: "signal_change" | "manual_action" | "schedule" | "webhook";
|
|
57
|
+
config: Record<string, any>;
|
|
58
|
+
};
|
|
59
|
+
actions: {
|
|
60
|
+
id: string;
|
|
61
|
+
type: "update_resource" | "send_notification" | "mqtt_publish" | "api_call" | "navigate" | "agent_task";
|
|
62
|
+
config: Record<string, any>;
|
|
63
|
+
}[];
|
|
64
|
+
}[];
|
|
65
|
+
};
|
|
66
|
+
modules?: string[];
|
|
67
|
+
resources?: {
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
fields: {
|
|
71
|
+
key: string;
|
|
72
|
+
label: string;
|
|
73
|
+
type: "number" | "boolean" | "text" | "currency" | "date" | "status" | "email" | "image" | "textarea";
|
|
74
|
+
required?: boolean;
|
|
75
|
+
description?: string;
|
|
76
|
+
defaultValue?: any;
|
|
77
|
+
}[];
|
|
78
|
+
defaultView?: "table" | "grid" | "list";
|
|
79
|
+
features?: {
|
|
80
|
+
searchable?: boolean;
|
|
81
|
+
creatable?: boolean;
|
|
82
|
+
editable?: boolean;
|
|
83
|
+
deletable?: boolean;
|
|
84
|
+
exportable?: boolean;
|
|
85
|
+
};
|
|
86
|
+
}[];
|
|
87
|
+
pages?: {
|
|
88
|
+
id: string;
|
|
89
|
+
slug: string;
|
|
90
|
+
title: string;
|
|
91
|
+
sections: {
|
|
92
|
+
id: string;
|
|
93
|
+
blocks: {
|
|
94
|
+
id: string;
|
|
95
|
+
type: string;
|
|
96
|
+
props: Record<string, any>;
|
|
97
|
+
layout?: {
|
|
98
|
+
colSpan?: number;
|
|
99
|
+
rowSpan?: number;
|
|
100
|
+
};
|
|
101
|
+
}[];
|
|
102
|
+
title?: string;
|
|
103
|
+
description?: string;
|
|
104
|
+
layout?: {
|
|
105
|
+
columns?: number;
|
|
106
|
+
variant?: "grid" | "stack" | "split";
|
|
107
|
+
};
|
|
108
|
+
}[];
|
|
109
|
+
description?: string;
|
|
110
|
+
icon?: string;
|
|
111
|
+
}[];
|
|
112
|
+
};
|
|
113
|
+
export declare const useBridgeStatus: () => "live" | "static";
|
|
114
|
+
export {};
|
|
115
|
+
//# sourceMappingURL=ManifestContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ManifestContext.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/ManifestContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiE,MAAM,OAAO,CAAC;AAEtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAS7D,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAgD5D,CAAC;AAIF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAMvB,CAAC;AAGF,eAAO,MAAM,eAAe,yBAG3B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useState, useRef } from 'react';
|
|
3
|
+
const ManifestContext = createContext(null);
|
|
4
|
+
export const ManifestProvider = ({ children, manifest: initialManifest }) => {
|
|
5
|
+
// 1. Initialize State
|
|
6
|
+
const [manifest, setManifest] = useState(initialManifest);
|
|
7
|
+
const [isLive, setIsLive] = useState(false);
|
|
8
|
+
// 2. Global Listener Guard (Refs persist across re-renders)
|
|
9
|
+
const isListening = useRef(false);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
// Prevent double-attaching listeners in StrictMode
|
|
12
|
+
if (isListening.current)
|
|
13
|
+
return;
|
|
14
|
+
isListening.current = true;
|
|
15
|
+
// A. Define the Listener
|
|
16
|
+
const handleMessage = (event) => {
|
|
17
|
+
// Security: Filter out noise, listen only for our specific event
|
|
18
|
+
if (event.data?.type === 'RAMME_SYNC_MANIFEST') {
|
|
19
|
+
const payload = event.data.payload;
|
|
20
|
+
// console.log("⚡️ [Context] Sync Received");
|
|
21
|
+
setManifest(payload);
|
|
22
|
+
setIsLive(true);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
// B. Attach Listener
|
|
26
|
+
window.addEventListener('message', handleMessage);
|
|
27
|
+
// C. Send Handshake (ONCE per session)
|
|
28
|
+
// We check a global window property to ensure we never spam the parent,
|
|
29
|
+
// even if this Provider is unmounted and remounted by React Router.
|
|
30
|
+
if (window.parent !== window && !window.__RAMME_HANDSHAKE_SENT) {
|
|
31
|
+
console.log("🔌 [Context] Handshake Sent 🤝");
|
|
32
|
+
window.parent.postMessage({ type: 'RAMME_CLIENT_READY' }, '*');
|
|
33
|
+
window.__RAMME_HANDSHAKE_SENT = true;
|
|
34
|
+
}
|
|
35
|
+
// Cleanup
|
|
36
|
+
return () => {
|
|
37
|
+
window.removeEventListener('message', handleMessage);
|
|
38
|
+
isListening.current = false;
|
|
39
|
+
};
|
|
40
|
+
}, []);
|
|
41
|
+
return (_jsx(ManifestContext.Provider, { value: { manifest, isLive }, children: children }));
|
|
42
|
+
};
|
|
43
|
+
// --- CONSUMER HOOKS ---
|
|
44
|
+
export const useManifest = () => {
|
|
45
|
+
const context = useContext(ManifestContext);
|
|
46
|
+
if (!context) {
|
|
47
|
+
throw new Error('useManifest must be used within a ManifestProvider');
|
|
48
|
+
}
|
|
49
|
+
return context.manifest;
|
|
50
|
+
};
|
|
51
|
+
// Returns 'live' | 'static' string to match your UI components
|
|
52
|
+
export const useBridgeStatus = () => {
|
|
53
|
+
const context = useContext(ManifestContext);
|
|
54
|
+
return context?.isLive ? 'live' : 'static';
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=ManifestContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ManifestContext.js","sourceRoot":"","sources":["../../../src/engine/runtime/ManifestContext.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAStF,MAAM,eAAe,GAAG,aAAa,CAA6B,IAAI,CAAC,CAAC;AAOxE,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,EAAE,EAAE;IAC3G,sBAAsB;IACtB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,eAAe,CAAC,CAAC;IAC5E,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE5C,4DAA4D;IAC5D,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAElC,SAAS,CAAC,GAAG,EAAE;QACb,mDAAmD;QACnD,IAAI,WAAW,CAAC,OAAO;YAAE,OAAO;QAChC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;QAE3B,yBAAyB;QACzB,MAAM,aAAa,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC5C,iEAAiE;YACjE,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,qBAAqB,EAAE,CAAC;gBAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBACnC,6CAA6C;gBAC7C,WAAW,CAAC,OAAO,CAAC,CAAC;gBACrB,SAAS,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QAEF,qBAAqB;QACrB,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAElD,uCAAuC;QACvC,wEAAwE;QACxE,oEAAoE;QACpE,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,CAAE,MAAc,CAAC,sBAAsB,EAAE,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,GAAG,CAAC,CAAC;YAC9D,MAAc,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACjD,CAAC;QAED,UAAU;QACV,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YACrD,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,YAClD,QAAQ,GACgB,CAC5B,CAAC;AACJ,CAAC,CAAC;AAEF,yBAAyB;AAEzB,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE;IAC9B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC,QAAQ,CAAC;AAC1B,CAAC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,OAAO,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC7C,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface MqttContextType {
|
|
3
|
+
isConnected: boolean;
|
|
4
|
+
lastMessage: Record<string, string>;
|
|
5
|
+
publish: (topic: string, message: string) => void;
|
|
6
|
+
subscribe: (topic: string) => void;
|
|
7
|
+
unsubscribe: (topic: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const MqttProvider: React.FC<{
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const useMqtt: () => MqttContextType;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=MqttContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MqttContext.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/MqttContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiE,MAAM,OAAO,CAAC;AAMtF,UAAU,eAAe;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAID,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAuEhE,CAAC;AAEF,eAAO,MAAM,OAAO,uBAInB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import mqtt from 'mqtt';
|
|
4
|
+
// ❌ REMOVED: import { appManifest } from '../../config/app.manifest';
|
|
5
|
+
// ✅ ADDED: Live Context
|
|
6
|
+
import { useManifest } from './ManifestContext';
|
|
7
|
+
const MqttContext = createContext(null);
|
|
8
|
+
export const MqttProvider = ({ children }) => {
|
|
9
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
10
|
+
const [lastMessage, setLastMessage] = useState({});
|
|
11
|
+
const clientRef = useRef(null);
|
|
12
|
+
const subscriptions = useRef(new Set());
|
|
13
|
+
// ✅ 1. Consume Live Manifest
|
|
14
|
+
const appManifest = useManifest();
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
// ✅ 2. Hot-Swap Broker Connection
|
|
17
|
+
// If you change the Broker URL in the Builder, this effect will re-run!
|
|
18
|
+
const brokerUrl = appManifest.config.brokerUrl || 'wss://test.mosquitto.org:8081';
|
|
19
|
+
console.log(`[MQTT] Connecting to ${brokerUrl}...`);
|
|
20
|
+
// Disconnect previous if exists
|
|
21
|
+
if (clientRef.current) {
|
|
22
|
+
clientRef.current.end();
|
|
23
|
+
}
|
|
24
|
+
const client = mqtt.connect(brokerUrl);
|
|
25
|
+
clientRef.current = client;
|
|
26
|
+
client.on('connect', () => {
|
|
27
|
+
console.log('[MQTT] Connected ✅');
|
|
28
|
+
setIsConnected(true);
|
|
29
|
+
// Re-subscribe to previous topics if needed
|
|
30
|
+
subscriptions.current.forEach(t => client.subscribe(t));
|
|
31
|
+
});
|
|
32
|
+
client.on('message', (topic, payload) => {
|
|
33
|
+
const messageStr = payload.toString();
|
|
34
|
+
setLastMessage((prev) => ({ ...prev, [topic]: messageStr }));
|
|
35
|
+
});
|
|
36
|
+
client.on('error', (err) => {
|
|
37
|
+
console.error('[MQTT] Connection error: ', err);
|
|
38
|
+
client.end();
|
|
39
|
+
});
|
|
40
|
+
return () => {
|
|
41
|
+
console.log('[MQTT] Disconnecting...');
|
|
42
|
+
client.end();
|
|
43
|
+
};
|
|
44
|
+
}, [appManifest.config.brokerUrl]); // Only re-connect if URL changes
|
|
45
|
+
const subscribe = (topic) => {
|
|
46
|
+
if (clientRef.current && !subscriptions.current.has(topic)) {
|
|
47
|
+
clientRef.current.subscribe(topic);
|
|
48
|
+
subscriptions.current.add(topic);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const unsubscribe = (topic) => {
|
|
52
|
+
if (clientRef.current && subscriptions.current.has(topic)) {
|
|
53
|
+
clientRef.current.unsubscribe(topic);
|
|
54
|
+
subscriptions.current.delete(topic);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const publish = (topic, message) => {
|
|
58
|
+
if (clientRef.current) {
|
|
59
|
+
clientRef.current.publish(topic, message);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
return (_jsx(MqttContext.Provider, { value: { isConnected, lastMessage, subscribe, unsubscribe, publish }, children: children }));
|
|
63
|
+
};
|
|
64
|
+
export const useMqtt = () => {
|
|
65
|
+
const context = useContext(MqttContext);
|
|
66
|
+
if (!context)
|
|
67
|
+
throw new Error('useMqtt must be used within an MqttProvider');
|
|
68
|
+
return context;
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=MqttContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MqttContext.js","sourceRoot":"","sources":["../../../src/engine/runtime/MqttContext.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtF,OAAO,IAAyB,MAAM,MAAM,CAAC;AAC7C,sEAAsE;AACtE,wBAAwB;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAUhD,MAAM,WAAW,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,YAAY,GAA4C,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACpF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAyB,EAAE,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAErD,6BAA6B;IAC7B,MAAM,WAAW,GAAG,WAAW,EAAE,CAAC;IAElC,SAAS,CAAC,GAAG,EAAE;QACb,kCAAkC;QAClC,wEAAwE;QACxE,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,SAAS,IAAI,+BAA+B,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,wBAAwB,SAAS,KAAK,CAAC,CAAC;QAEpD,gCAAgC;QAChC,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACpB,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACvC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;QAE3B,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,cAAc,CAAC,IAAI,CAAC,CAAC;YACrB,4CAA4C;YAC5C,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,KAAa,EAAE,OAAe,EAAE,EAAE;YACtD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,iCAAiC;IAErE,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,EAAE;QAClC,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACnC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,EAAE;QACpC,IAAI,SAAS,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACrC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,OAAe,EAAE,EAAE;QACjD,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,YACvF,QAAQ,GACY,CACxB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE;IAC1B,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC7E,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SitemapContext.tsx
|
|
3
|
+
* @repository ramme-app-starter
|
|
4
|
+
* @description This file implements a React Context for the sitemap.
|
|
5
|
+
*
|
|
6
|
+
* STRATEGIC IMPORTANCE:
|
|
7
|
+
* This context is the "plumbing" that makes our swappable layout
|
|
8
|
+
* strategy possible. It allows a top-level layout component (like
|
|
9
|
+
* `DashboardLayout.tsx` or `DocsLayout.tsx`) to "provide" its specific
|
|
10
|
+
* sitemap array (e.g., `dashboard.sitemap.ts`) to all of its children.
|
|
11
|
+
*
|
|
12
|
+
* Any component deep in the tree (like a sidebar, breadcrumbs, or page
|
|
13
|
+
* header) can then "consume" this sitemap data using the `useSitemap`
|
|
14
|
+
* hook to render the correct navigation, titles, and icons.
|
|
15
|
+
*
|
|
16
|
+
* This effectively decouples the navigation UI from the sitemap data,
|
|
17
|
+
* allowing us to change the entire application's IA simply by changing
|
|
18
|
+
* the data provided by the `SitemapProvider`.
|
|
19
|
+
*/
|
|
20
|
+
import type { SitemapEntry } from '../types/sitemap-entry';
|
|
21
|
+
/**
|
|
22
|
+
* A custom hook to easily access the active sitemap array.
|
|
23
|
+
* This abstracts the `useContext` logic and provides a clean API
|
|
24
|
+
* for components that need to read the sitemap.
|
|
25
|
+
*
|
|
26
|
+
* @returns {SitemapEntry[]} The sitemap array provided by the nearest
|
|
27
|
+
* `SitemapProvider`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const useSitemap: () => SitemapEntry[];
|
|
30
|
+
export declare const SitemapProvider: import("react").Provider<SitemapEntry[]>;
|
|
31
|
+
//# sourceMappingURL=SitemapContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SitemapContext.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/SitemapContext.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,sBAWtB,CAAC;AAYF,eAAO,MAAM,eAAe,0CAA0B,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SitemapContext.tsx
|
|
3
|
+
* @repository ramme-app-starter
|
|
4
|
+
* @description This file implements a React Context for the sitemap.
|
|
5
|
+
*
|
|
6
|
+
* STRATEGIC IMPORTANCE:
|
|
7
|
+
* This context is the "plumbing" that makes our swappable layout
|
|
8
|
+
* strategy possible. It allows a top-level layout component (like
|
|
9
|
+
* `DashboardLayout.tsx` or `DocsLayout.tsx`) to "provide" its specific
|
|
10
|
+
* sitemap array (e.g., `dashboard.sitemap.ts`) to all of its children.
|
|
11
|
+
*
|
|
12
|
+
* Any component deep in the tree (like a sidebar, breadcrumbs, or page
|
|
13
|
+
* header) can then "consume" this sitemap data using the `useSitemap`
|
|
14
|
+
* hook to render the correct navigation, titles, and icons.
|
|
15
|
+
*
|
|
16
|
+
* This effectively decouples the navigation UI from the sitemap data,
|
|
17
|
+
* allowing us to change the entire application's IA simply by changing
|
|
18
|
+
* the data provided by the `SitemapProvider`.
|
|
19
|
+
*/
|
|
20
|
+
import { createContext, useContext } from 'react';
|
|
21
|
+
// 1. Create the context
|
|
22
|
+
// We initialize it with an empty array as a safe default.
|
|
23
|
+
// This context will hold the sitemap array specific to the active layout.
|
|
24
|
+
const SitemapContext = createContext([]);
|
|
25
|
+
/**
|
|
26
|
+
* A custom hook to easily access the active sitemap array.
|
|
27
|
+
* This abstracts the `useContext` logic and provides a clean API
|
|
28
|
+
* for components that need to read the sitemap.
|
|
29
|
+
*
|
|
30
|
+
* @returns {SitemapEntry[]} The sitemap array provided by the nearest
|
|
31
|
+
* `SitemapProvider`.
|
|
32
|
+
*/
|
|
33
|
+
export const useSitemap = () => {
|
|
34
|
+
const context = useContext(SitemapContext);
|
|
35
|
+
// This is a critical developer-friendly check.
|
|
36
|
+
// If a component tries to call `useSitemap` outside of a layout
|
|
37
|
+
// that provides the context, we throw an explicit error.
|
|
38
|
+
if (context === undefined) {
|
|
39
|
+
throw new Error('useSitemap must be used within a SitemapProvider');
|
|
40
|
+
}
|
|
41
|
+
return context;
|
|
42
|
+
};
|
|
43
|
+
// 3. Export the Provider
|
|
44
|
+
// We export the Provider component directly. This is what our layout
|
|
45
|
+
// components will use to wrap their content and supply the sitemap data.
|
|
46
|
+
//
|
|
47
|
+
// Example Usage (in a layout file):
|
|
48
|
+
// <SitemapProvider value={dashboardSitemap}>
|
|
49
|
+
// <AppHeader />
|
|
50
|
+
// <AppSidebar />
|
|
51
|
+
// <Outlet />
|
|
52
|
+
// </SitemapProvider>
|
|
53
|
+
export const SitemapProvider = SitemapContext.Provider;
|
|
54
|
+
//# sourceMappingURL=SitemapContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SitemapContext.js","sourceRoot":"","sources":["../../../src/engine/runtime/SitemapContext.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAIlD,wBAAwB;AACxB,0DAA0D;AAC1D,0EAA0E;AAC1E,MAAM,cAAc,GAAG,aAAa,CAAiB,EAAE,CAAC,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE;IAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAE3C,+CAA+C;IAC/C,gEAAgE;IAChE,yDAAyD;IACzD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,yBAAyB;AACzB,qEAAqE;AACrE,yEAAyE;AACzE,EAAE;AACF,oCAAoC;AACpC,6CAA6C;AAC7C,kBAAkB;AAClB,mBAAmB;AACnB,eAAe;AACf,qBAAqB;AACrB,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,QAAQ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file data-seeder.ts
|
|
3
|
+
* @description The "Big Bang" for the client-side database.
|
|
4
|
+
* * ARCHITECTURAL ROLE:
|
|
5
|
+
* This utility ensures that the LocalStorage "Data Lake" is never empty.
|
|
6
|
+
* On app launch, it checks if data exists. If not, it writes the seed data
|
|
7
|
+
* provided by the Kernel/Manifest into the browser's storage.
|
|
8
|
+
*/
|
|
9
|
+
export declare const initializeDataLake: (registry: Record<string, any[]>) => void;
|
|
10
|
+
//# sourceMappingURL=data-seeder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-seeder.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/data-seeder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,SAyBjE,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file data-seeder.ts
|
|
3
|
+
* @description The "Big Bang" for the client-side database.
|
|
4
|
+
* * ARCHITECTURAL ROLE:
|
|
5
|
+
* This utility ensures that the LocalStorage "Data Lake" is never empty.
|
|
6
|
+
* On app launch, it checks if data exists. If not, it writes the seed data
|
|
7
|
+
* provided by the Kernel/Manifest into the browser's storage.
|
|
8
|
+
*/
|
|
9
|
+
// 🔒 CRITICAL FIX: Changed from 'ramme_mock_' to 'ramme_db_' to match AuthContext
|
|
10
|
+
// This ensures that the AuthProvider can actually find the 'users' table we seed.
|
|
11
|
+
const DB_PREFIX = 'ramme_db_';
|
|
12
|
+
export const initializeDataLake = (registry) => {
|
|
13
|
+
if (typeof window === 'undefined')
|
|
14
|
+
return;
|
|
15
|
+
// Safety check: Don't crash if the registry is missing (e.g. during early boot)
|
|
16
|
+
if (!registry) {
|
|
17
|
+
console.warn('⚠️ [Data Lake] No registry provided to seeder. Skipping initialization.');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.groupCollapsed('🌊 [Data Lake] Initialization');
|
|
21
|
+
Object.entries(registry).forEach(([key, seedData]) => {
|
|
22
|
+
const storageKey = `${DB_PREFIX}${key}`;
|
|
23
|
+
const existing = localStorage.getItem(storageKey);
|
|
24
|
+
if (!existing) {
|
|
25
|
+
console.log(`✨ Seeding collection: ${key}`);
|
|
26
|
+
localStorage.setItem(storageKey, JSON.stringify(seedData));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Optional: Debug log for existing data (helps verify persistence)
|
|
30
|
+
// console.log(`✅ Found existing data for: ${key}`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
console.groupEnd();
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=data-seeder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-seeder.js","sourceRoot":"","sources":["../../../src/engine/runtime/data-seeder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,kFAAkF;AAClF,kFAAkF;AAClF,MAAM,SAAS,GAAG,WAAW,CAAC;AAE9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAA+B,EAAE,EAAE;IACpE,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAE1C,gFAAgF;IAChF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QACxF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,cAAc,CAAC,+BAA+B,CAAC,CAAC;IAExD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,EAAE;QACnD,MAAM,UAAU,GAAG,GAAG,SAAS,GAAG,GAAG,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAElD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;YAC5C,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACJ,mEAAmE;YACnE,oDAAoD;QACxD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,QAAQ,EAAE,CAAC;AACrB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAction.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useAction.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS;2BAO4B,MAAM,SAAS,GAAG;CAkDnE,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useMqtt } from './MqttContext';
|
|
3
|
+
// ❌ REMOVED: import { appManifest } from '../../config/app.manifest';
|
|
4
|
+
// ✅ ADDED: Live Context
|
|
5
|
+
import { useManifest } from './ManifestContext';
|
|
6
|
+
export const useAction = () => {
|
|
7
|
+
const { publish, isConnected } = useMqtt();
|
|
8
|
+
// ✅ 1. Consume Live Manifest
|
|
9
|
+
const appManifest = useManifest();
|
|
10
|
+
const { config, domain } = appManifest;
|
|
11
|
+
const sendAction = useCallback(async (entityId, value) => {
|
|
12
|
+
// 2. Find the Entity definition (Live)
|
|
13
|
+
const entity = domain.entities.find(e => e.id === entityId);
|
|
14
|
+
if (!entity) {
|
|
15
|
+
console.warn(`[Action] Entity ID '${entityId}' not found in manifest.`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const signalId = entity.signals[0];
|
|
19
|
+
const signal = domain.signals.find(s => s.id === signalId);
|
|
20
|
+
if (!signal) {
|
|
21
|
+
console.warn(`[Action] No signal linked to entity: ${entityId}`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// --- Mock Mode ---
|
|
25
|
+
if (config.mockMode) {
|
|
26
|
+
console.log(`%c[Mock Action] Setting ${entity.name} to:`, 'color: #10b981; font-weight: bold;', value);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// --- Live Mode (MQTT) ---
|
|
30
|
+
if (signal.source === 'mqtt' && signal.topic) {
|
|
31
|
+
if (!isConnected) {
|
|
32
|
+
console.warn('[Action] Cannot send: MQTT disconnected');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const payload = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
36
|
+
console.log(`[MQTT] Publishing to '${signal.topic}': ${payload}`);
|
|
37
|
+
publish(signal.topic, payload);
|
|
38
|
+
}
|
|
39
|
+
// --- Live Mode (HTTP) ---
|
|
40
|
+
if (signal.source === 'http' && signal.endpoint) {
|
|
41
|
+
try {
|
|
42
|
+
await fetch(signal.endpoint, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: { 'Content-Type': 'application/json' },
|
|
45
|
+
body: JSON.stringify({ id: signal.id, value })
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.log('[HTTP] (Simulation) Request sent.');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}, [config.mockMode, isConnected, publish, domain]);
|
|
53
|
+
return { sendAction };
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=useAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAction.js","sourceRoot":"","sources":["../../../src/engine/runtime/useAction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hook useCrudLocalStorage
|
|
3
|
+
* @description A generic hook for performing CRUD (Create, Read, Update, Delete)
|
|
4
|
+
* operations on an array of items stored in the browser's localStorage.
|
|
5
|
+
* * It serves as the "Database Engine" for the mock runtime.
|
|
6
|
+
*
|
|
7
|
+
* @param storageKey The unique key for this data in localStorage (e.g., 'ramme_db_users').
|
|
8
|
+
* @param initialData The default data to seed localStorage with if it's empty.
|
|
9
|
+
* @returns An object with the current data and functions to manipulate it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const useCrudLocalStorage: <T extends {
|
|
12
|
+
id: any;
|
|
13
|
+
}>(storageKey: string, initialData: T[]) => {
|
|
14
|
+
data: T[];
|
|
15
|
+
createItem: (newItem: Omit<T, "id">) => void;
|
|
16
|
+
updateItem: (updatedItem: T) => void;
|
|
17
|
+
deleteItem: (id: T["id"]) => void;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=useCrudLocalStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCrudLocalStorage.d.ts","sourceRoot":"","sources":["../../../src/engine/runtime/useCrudLocalStorage.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS;IAAE,EAAE,EAAE,GAAG,CAAA;CAAE,EACvD,YAAY,MAAM,EAClB,aAAa,CAAC,EAAE;;0BAuByB,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;8BAwBT,CAAC;qBAWV,CAAC,CAAC,IAAI,CAAC;CAS5C,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @hook useCrudLocalStorage
|
|
4
|
+
* @description A generic hook for performing CRUD (Create, Read, Update, Delete)
|
|
5
|
+
* operations on an array of items stored in the browser's localStorage.
|
|
6
|
+
* * It serves as the "Database Engine" for the mock runtime.
|
|
7
|
+
*
|
|
8
|
+
* @param storageKey The unique key for this data in localStorage (e.g., 'ramme_db_users').
|
|
9
|
+
* @param initialData The default data to seed localStorage with if it's empty.
|
|
10
|
+
* @returns An object with the current data and functions to manipulate it.
|
|
11
|
+
*/
|
|
12
|
+
export const useCrudLocalStorage = (storageKey, initialData) => {
|
|
13
|
+
// 1. Initialize State from LocalStorage
|
|
14
|
+
const [data, setData] = useState(() => {
|
|
15
|
+
// Safety check for Server-Side Rendering
|
|
16
|
+
if (typeof window === 'undefined')
|
|
17
|
+
return initialData;
|
|
18
|
+
try {
|
|
19
|
+
const item = window.localStorage.getItem(storageKey);
|
|
20
|
+
if (item) {
|
|
21
|
+
return JSON.parse(item);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
// Seed the "DB" if empty
|
|
25
|
+
window.localStorage.setItem(storageKey, JSON.stringify(initialData));
|
|
26
|
+
return initialData;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(`[Data Lake] Error reading key "${storageKey}":`, error);
|
|
31
|
+
return initialData;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
// 2. CREATE
|
|
35
|
+
const createItem = useCallback((newItem) => {
|
|
36
|
+
setData(prevData => {
|
|
37
|
+
// ✅ ROBUST ID GENERATION (Zero Jank)
|
|
38
|
+
// Detects if existing IDs are Numbers or Strings to prevent type conflicts.
|
|
39
|
+
let newId;
|
|
40
|
+
const isNumeric = prevData.length > 0 && typeof prevData[0].id === 'number';
|
|
41
|
+
if (isNumeric) {
|
|
42
|
+
const maxId = prevData.reduce((max, item) => (typeof item.id === 'number' && item.id > max ? item.id : max), 0);
|
|
43
|
+
newId = maxId + 1;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Fallback for string IDs (e.g. 'usr_17354...')
|
|
47
|
+
newId = `id_${Date.now()}`;
|
|
48
|
+
}
|
|
49
|
+
const fullNewItem = { ...newItem, id: newId };
|
|
50
|
+
const updatedData = [...prevData, fullNewItem];
|
|
51
|
+
window.localStorage.setItem(storageKey, JSON.stringify(updatedData));
|
|
52
|
+
return updatedData;
|
|
53
|
+
});
|
|
54
|
+
}, [storageKey]);
|
|
55
|
+
// 3. UPDATE
|
|
56
|
+
const updateItem = useCallback((updatedItem) => {
|
|
57
|
+
setData(prevData => {
|
|
58
|
+
const updatedData = prevData.map(item => item.id === updatedItem.id ? updatedItem : item);
|
|
59
|
+
window.localStorage.setItem(storageKey, JSON.stringify(updatedData));
|
|
60
|
+
return updatedData;
|
|
61
|
+
});
|
|
62
|
+
}, [storageKey]);
|
|
63
|
+
// 4. DELETE
|
|
64
|
+
const deleteItem = useCallback((id) => {
|
|
65
|
+
setData(prevData => {
|
|
66
|
+
const updatedData = prevData.filter(item => item.id !== id);
|
|
67
|
+
window.localStorage.setItem(storageKey, JSON.stringify(updatedData));
|
|
68
|
+
return updatedData;
|
|
69
|
+
});
|
|
70
|
+
}, [storageKey]);
|
|
71
|
+
return { data, createItem, updateItem, deleteItem };
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=useCrudLocalStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCrudLocalStorage.js","sourceRoot":"","sources":["../../../src/engine/runtime/useCrudLocalStorage.ts"],"names":[],"mappings":"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"}
|