@warpfx/nui-core 0.1.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.
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @warp/nui-core — Framework-agnostic NUI bridge.
3
+ *
4
+ * Runs inside the FiveM CEF browser. Provides a message bus between
5
+ * the FiveM client V8 runtime and the browser UI.
6
+ *
7
+ * Works with any JS framework (Vue, React, Svelte, vanilla) or none.
8
+ *
9
+ * Communication:
10
+ * - Client → NUI: SendNUIMessage → window.message event
11
+ * - NUI → Client: fetch('https://warp/...') → RegisterNUICallback
12
+ */
13
+ type Unsubscribe = () => void;
14
+ type VisibilityHandler = (panel?: string) => void;
15
+ declare class WarpBridge {
16
+ private state;
17
+ private syncHandlers;
18
+ private showHandlers;
19
+ private hideHandlers;
20
+ private _visible;
21
+ private _panel;
22
+ private constructor();
23
+ /**
24
+ * Initialize the NUI bridge. Returns a singleton — safe to call
25
+ * multiple times from different modules.
26
+ */
27
+ static init(): WarpBridge;
28
+ /** Whether the NUI is currently visible. */
29
+ get visible(): boolean;
30
+ /** The currently active panel name, if any. */
31
+ get panel(): string | undefined;
32
+ /** Get current state for a key. */
33
+ getState<T>(key: string): T | undefined;
34
+ /**
35
+ * Subscribe to synced state updates for a key.
36
+ * Fires immediately with current state if available.
37
+ * Returns an unsubscribe function.
38
+ */
39
+ onSync<T>(key: string, callback: (state: T) => void): Unsubscribe;
40
+ /** Dispatch an action to the server via the FiveM client. */
41
+ action(name: string, payload?: any): void;
42
+ /** Request the client to close/hide the NUI. */
43
+ close(): void;
44
+ /** Register a callback for when the NUI becomes visible. */
45
+ onShow(callback: VisibilityHandler): Unsubscribe;
46
+ /** Register a callback for when the NUI is hidden. */
47
+ onHide(callback: () => void): Unsubscribe;
48
+ private handleSync;
49
+ private handleVisibility;
50
+ }
51
+
52
+ export { WarpBridge };
package/dist/index.js ADDED
@@ -0,0 +1,140 @@
1
+ // src/index.ts
2
+ var WarpBridge = class _WarpBridge {
3
+ state = /* @__PURE__ */ new Map();
4
+ syncHandlers = /* @__PURE__ */ new Map();
5
+ showHandlers = /* @__PURE__ */ new Set();
6
+ hideHandlers = /* @__PURE__ */ new Set();
7
+ _visible = false;
8
+ _panel;
9
+ constructor() {
10
+ window.addEventListener("message", (event) => {
11
+ const data = event.data;
12
+ if (!data || typeof data !== "object") return;
13
+ if (data.type === "warp:sync") {
14
+ this.handleSync(data);
15
+ } else if (data.type === "warp:visibility") {
16
+ this.handleVisibility(data.visible, data.panel);
17
+ }
18
+ });
19
+ }
20
+ /**
21
+ * Initialize the NUI bridge. Returns a singleton — safe to call
22
+ * multiple times from different modules.
23
+ */
24
+ static init() {
25
+ if (!window.__warpBridge) {
26
+ window.__warpBridge = new _WarpBridge();
27
+ }
28
+ return window.__warpBridge;
29
+ }
30
+ // -------------------------------------------------------------------------
31
+ // State
32
+ // -------------------------------------------------------------------------
33
+ /** Whether the NUI is currently visible. */
34
+ get visible() {
35
+ return this._visible;
36
+ }
37
+ /** The currently active panel name, if any. */
38
+ get panel() {
39
+ return this._panel;
40
+ }
41
+ /** Get current state for a key. */
42
+ getState(key) {
43
+ return this.state.get(key);
44
+ }
45
+ // -------------------------------------------------------------------------
46
+ // Sync subscriptions
47
+ // -------------------------------------------------------------------------
48
+ /**
49
+ * Subscribe to synced state updates for a key.
50
+ * Fires immediately with current state if available.
51
+ * Returns an unsubscribe function.
52
+ */
53
+ onSync(key, callback) {
54
+ if (!this.syncHandlers.has(key)) {
55
+ this.syncHandlers.set(key, /* @__PURE__ */ new Set());
56
+ }
57
+ const set = this.syncHandlers.get(key);
58
+ set.add(callback);
59
+ const current = this.state.get(key);
60
+ if (current !== void 0) {
61
+ try {
62
+ callback(current);
63
+ } catch {
64
+ }
65
+ }
66
+ return () => set.delete(callback);
67
+ }
68
+ // -------------------------------------------------------------------------
69
+ // Actions
70
+ // -------------------------------------------------------------------------
71
+ /** Dispatch an action to the server via the FiveM client. */
72
+ action(name, payload) {
73
+ fetch("https://warp/action", {
74
+ method: "POST",
75
+ body: JSON.stringify({ name, payload })
76
+ }).catch(() => {
77
+ });
78
+ }
79
+ /** Request the client to close/hide the NUI. */
80
+ close() {
81
+ fetch("https://warp/close", {
82
+ method: "POST",
83
+ body: JSON.stringify({})
84
+ }).catch(() => {
85
+ });
86
+ }
87
+ // -------------------------------------------------------------------------
88
+ // Visibility events
89
+ // -------------------------------------------------------------------------
90
+ /** Register a callback for when the NUI becomes visible. */
91
+ onShow(callback) {
92
+ this.showHandlers.add(callback);
93
+ return () => this.showHandlers.delete(callback);
94
+ }
95
+ /** Register a callback for when the NUI is hidden. */
96
+ onHide(callback) {
97
+ this.hideHandlers.add(callback);
98
+ return () => this.hideHandlers.delete(callback);
99
+ }
100
+ // -------------------------------------------------------------------------
101
+ // Internal
102
+ // -------------------------------------------------------------------------
103
+ handleSync(data) {
104
+ for (const [key, value] of Object.entries(data)) {
105
+ if (key === "type") continue;
106
+ this.state.set(key, value);
107
+ const handlers = this.syncHandlers.get(key);
108
+ if (handlers) {
109
+ for (const fn of handlers) {
110
+ try {
111
+ fn(value);
112
+ } catch {
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ handleVisibility(visible, panel) {
119
+ this._visible = visible;
120
+ this._panel = panel;
121
+ if (visible) {
122
+ for (const fn of this.showHandlers) {
123
+ try {
124
+ fn(panel);
125
+ } catch {
126
+ }
127
+ }
128
+ } else {
129
+ for (const fn of this.hideHandlers) {
130
+ try {
131
+ fn();
132
+ } catch {
133
+ }
134
+ }
135
+ }
136
+ }
137
+ };
138
+ export {
139
+ WarpBridge
140
+ };
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@warpfx/nui-core",
3
+ "version": "0.1.0",
4
+ "description": "Warp Framework — Framework-agnostic NUI bridge for FiveM",
5
+ "keywords": [
6
+ "fivem",
7
+ "framework",
8
+ "nui",
9
+ "warp"
10
+ ],
11
+ "type": "module",
12
+ "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/1camou/warp.git",
16
+ "directory": "packages/nui-core"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "main": "dist/index.js",
22
+ "types": "dist/index.d.ts",
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "scripts": {
27
+ "build": "tsup src/index.ts --format esm --dts --out-dir dist"
28
+ }
29
+ }