cabbage-react 1.0.30 → 1.0.32

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/README.md CHANGED
@@ -18,19 +18,39 @@ npm install cabbage-react
18
18
 
19
19
  ### useCabbageState
20
20
 
21
- Synchronize a parameter with the backend. This hook:
21
+ Synchronize a channel with the backend. This hook:
22
22
 
23
- - Identifies and sets the default value defined in .csd to a state.
24
- - Handles initialization when opening an existing session, or reopening the plugin window.
25
- - Listens for value updates from the host (DAW), or from Csound.
26
- - Sends changes to the backend using the provided value-setter.
23
+ - Automatically updates local state when value is received or changed
24
+ - Sends changes to the backend using the provided value-setter
27
25
 
28
26
  ### useCabbageProperties
29
27
 
30
- Get properties for a parameter from the backend. This hook:
28
+ Get properties for a widget from the backend. This hook:
31
29
 
32
- - Listens for property updates from the backend.
33
- - Updates local state automatically when data changes.
30
+ - Automatically updates local state when properties are received or changed
31
+
32
+ ### useCabbageMessage
33
+
34
+ Get messages from the backend. This hook:
35
+
36
+ - Automatically updates local state when a message is received
37
+ - Expects a serialized JSON object (sent as a string) with an `id` property
38
+
39
+ #### Example: sending a message from Csound
40
+
41
+ ```csd
42
+ jsonData:S = sprintf({{
43
+ {
44
+ "id":"NoteData",
45
+ "noteCount":%f,
46
+ "note":%f,
47
+ "noteLength":%f,
48
+ "noteVelocity":%f
49
+ }
50
+ }}, iNoteCount, iNote, iLength, iVelocity)
51
+
52
+ cabbageSendMessage(jsonData)
53
+ ```
34
54
 
35
55
  ## Usage
36
56
 
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Custom hook to get a message from Cabbage backend.
3
+ * This hook listens to messages sent from the backend and updates the local state
4
+ * whenever new data is received.
5
+ * @param messageId
6
+ */
7
+ export declare const useCabbageMessage: <T>(messageId: string) => {
8
+ message: T | undefined;
9
+ };
10
+ //# sourceMappingURL=useCabbageMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCabbageMessage.d.ts","sourceRoot":"","sources":["../../src/hooks/useCabbageMessage.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,aAAa,MAAM;;CAgCrD,CAAC"}
@@ -2,7 +2,7 @@
2
2
  * Custom hook to get a parameter's properties from Cabbage backend.
3
3
  * This hook listens for updates to parameter properties from the backend and updates the local state
4
4
  * whenever new data is received.
5
- * @param channelId - The channel name
5
+ * @param channelId
6
6
  */
7
7
  export declare const useCabbageProperties: (channelId: string) => {
8
8
  properties: Record<string, any> | undefined;
@@ -2,7 +2,7 @@
2
2
  * Custom hook to sync a parameter with Cabbage backend.
3
3
  * This hook listens for updates to a parameter value from the backend and
4
4
  * sends updates to the backend when the parameter value changes locally (e.g., through a UI slider).
5
- * @param channelId - The channel name
5
+ * @param channelId
6
6
  * @param gesture - The gesture type: "begin" (start of interaction), "value" (during interaction), "end" (end of continuous interaction), or "complete" (discrete action e.g. button click).
7
7
  */
8
8
  export declare const useCabbageState: <T>(channelId: string, gesture?: "begin" | "value" | "end" | "complete") => {
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react");console.log("Cabbage: loading cabbage.js");class p{static sendControlData({channel:o,value:e,gesture:s="complete"},a=null){const n={command:"controlData",channel:o,value:e,gesture:s};a!==null?a.postMessage(n):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(n):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",n)}static isReadyToLoad(o=null,e={}){this.sendCustomCommand("isReadyToLoad",o)}static sendMidiMessageFromUI(o,e,s,a=null){var n={statusByte:o,dataByte1:e,dataByte2:s};const d={command:"midiMessage",obj:JSON.stringify(n)};a!==null?a.postMessage(d):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(d):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",d)}static MidiMessageFromHost(o,e,s){console.log("Cabbage: Got MIDI Message"+o+":"+e+":"+s)}static triggerFileOpenDialog(o,e,s={}){var a={channel:e,directory:s.directory||"",filters:s.filters||"*",openAtLastKnownLocation:s.openAtLastKnownLocation!==void 0?s.openAtLastKnownLocation:!0};const n={command:"fileOpen",obj:JSON.stringify(a)};o!==null?o.postMessage(n):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(n):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",n)}static openUrl(o,e,s){var a={url:e,file:s};const n={command:"openUrl",obj:JSON.stringify(a)};o!==null?o.postMessage(n):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(n):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",n)}static requestResize(o,e,s=null){const a={command:"requestResize",width:o,height:e};if(s!==null){console.warn("Cabbage: requestResize is not supported in VS Code extension mode");return}else typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(a):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",a)}static sendChannelData(o,e,s=null){var a={channel:o};if(typeof e=="string")a.stringData=e;else if(typeof e=="number")a.floatData=e;else{console.warn("Cabbage: sendChannelData received unsupported data type:",typeof e);return}const n={command:"channelData",obj:JSON.stringify(a)};console.log("Cabbage: sending channel data from UI",a),s!==null?s.postMessage(n):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(n):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",n)}static sendWidgetUpdate(o,e=null){const s={command:"widgetStateUpdate",obj:JSON.stringify(CabbageUtils.sanitizeForEditor(o))};e!==null?e.postMessage(s):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(s):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",s)}static sendCustomCommand(o,e=null,s={}){const a={command:o,text:JSON.stringify(s)};if(e!==null)e.postMessage(a);else if(typeof window.sendMessageFromUI=="function"){console.log("Cabbage: Calling window.sendMessageFromUI with:",a);try{const n=window.sendMessageFromUI(a);console.log("Cabbage: sendMessageFromUI returned:",n)}catch(n){console.error("Cabbage: sendMessageFromUI threw error:",n),console.error("Cabbage: Error stack:",n.stack)}}else console.error("Cabbage: window.sendMessageFromUI is not available yet. Message:",a),console.error("Cabbage: typeof window.sendMessageFromUI:",typeof window.sendMessageFromUI),console.error("Cabbage: window.sendMessageFromUI value:",window.sendMessageFromUI)}}const C=r=>{const[o,e]=m.useState();return m.useEffect(()=>{const s=a=>{const{id:n,widgetJson:d,command:w}=a.data;if(n===r&&d&&w==="widgetUpdate"){const t=JSON.parse(d);console.log(`[Cabbage-React] Received properties for channelId ${n}`,t),e(t)}};return window.addEventListener("message",s),()=>{window.removeEventListener("message",s)}},[]),{properties:o}},I=(r,o="complete")=>{const{properties:e}=C(r),[s,a]=m.useState(),[n,d]=m.useState(),w=t=>{a(t),p.sendControlData({channel:r,value:t,gesture:o})};return m.useEffect(()=>{var b;const t=e==null?void 0:e.channels.find(i=>i.id===r);if(!t)return;const l=t==null?void 0:t.parameterIndex;n===void 0&&l!==void 0&&(console.log(`[Cabbage-React] Received parameterIndex for channelId "${t.id}"`,l),d(l));const g=(b=t.range)==null?void 0:b.defaultValue;s===void 0&&g!==void 0&&(console.log(`[Cabbage-React] Received default value for channelId "${t.id}"`,g),a(g))},[e]),m.useEffect(()=>{const t=l=>{var b;const{command:g}=l.data;if(g==="parameterChange"){const{value:i,paramIdx:c}=l.data.data;if(c!==n||i===null)return;console.log(`[Cabbage-React] Received parameterChange for parameterIndex ${c}`,i),a(i)}else if(g==="batchWidgetUpdate"){const i=l.data.widgets,c=i==null?void 0:i.find(f=>f.id===r);if(!c)return;const u=JSON.parse(c.widgetJson).channels.find(f=>f.id===r),M=(b=u==null?void 0:u.range)==null?void 0:b.value;console.log(`[Cabbage-React] Received batch widget update for channelId ${c.id}`,M),a(M)}};return window.addEventListener("message",t),()=>{window.removeEventListener("message",t)}},[n]),{value:s,setValue:w}};exports.Cabbage=p;exports.useCabbageProperties=C;exports.useCabbageState=I;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react");console.log("Cabbage: loading cabbage.js");class p{static sendControlData({channel:o,value:e,gesture:s="complete"},n=null){const a={command:"controlData",channel:o,value:e,gesture:s};n!==null?n.postMessage(a):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(a):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",a)}static isReadyToLoad(o=null,e={}){this.sendCustomCommand("isReadyToLoad",o)}static sendMidiMessageFromUI(o,e,s,n=null){var a={statusByte:o,dataByte1:e,dataByte2:s};const r={command:"midiMessage",obj:JSON.stringify(a)};n!==null?n.postMessage(r):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(r):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",r)}static MidiMessageFromHost(o,e,s){console.log("Cabbage: Got MIDI Message"+o+":"+e+":"+s)}static triggerFileOpenDialog(o,e,s={}){var n={channel:e,directory:s.directory||"",filters:s.filters||"*",openAtLastKnownLocation:s.openAtLastKnownLocation!==void 0?s.openAtLastKnownLocation:!0};const a={command:"fileOpen",obj:JSON.stringify(n)};o!==null?o.postMessage(a):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(a):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",a)}static openUrl(o,e,s){var n={url:e,file:s};const a={command:"openUrl",obj:JSON.stringify(n)};o!==null?o.postMessage(a):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(a):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",a)}static requestResize(o,e,s=null){const n={command:"requestResize",width:o,height:e};if(s!==null){console.warn("Cabbage: requestResize is not supported in VS Code extension mode");return}else typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(n):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",n)}static sendChannelData(o,e,s=null){var n={channel:o};if(typeof e=="string")n.stringData=e;else if(typeof e=="number")n.floatData=e;else{console.warn("Cabbage: sendChannelData received unsupported data type:",typeof e);return}const a={command:"channelData",obj:JSON.stringify(n)};console.log("Cabbage: sending channel data from UI",n),s!==null?s.postMessage(a):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(a):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",a)}static sendWidgetUpdate(o,e=null){const s={command:"widgetStateUpdate",obj:JSON.stringify(CabbageUtils.sanitizeForEditor(o))};e!==null?e.postMessage(s):typeof window.sendMessageFromUI=="function"?window.sendMessageFromUI(s):console.error("Cabbage: window.sendMessageFromUI is not available. Message:",s)}static sendCustomCommand(o,e=null,s={}){const n={command:o,text:JSON.stringify(s)};if(e!==null)e.postMessage(n);else if(typeof window.sendMessageFromUI=="function"){console.log("Cabbage: Calling window.sendMessageFromUI with:",n);try{const a=window.sendMessageFromUI(n);console.log("Cabbage: sendMessageFromUI returned:",a)}catch(a){console.error("Cabbage: sendMessageFromUI threw error:",a),console.error("Cabbage: Error stack:",a.stack)}}else console.error("Cabbage: window.sendMessageFromUI is not available yet. Message:",n),console.error("Cabbage: typeof window.sendMessageFromUI:",typeof window.sendMessageFromUI),console.error("Cabbage: window.sendMessageFromUI value:",window.sendMessageFromUI)}}const C=i=>{const[o,e]=l.useState();return l.useEffect(()=>{const s=n=>{const{id:a,widgetJson:r,command:g}=n.data;if(a===i&&r&&g==="widgetUpdate"){const t=JSON.parse(r);console.log(`[Cabbage-React] Received properties for channelId ${a}`,t),e(t)}};return window.addEventListener("message",s),()=>{window.removeEventListener("message",s)}},[]),{properties:o}},I=(i,o="complete")=>{const{properties:e}=C(i),[s,n]=l.useState(),[a,r]=l.useState(),g=t=>{n(t),p.sendControlData({channel:i,value:t,gesture:o})};return l.useEffect(()=>{var u;const t=e==null?void 0:e.channels.find(d=>d.id===i);if(!t)return;const c=t==null?void 0:t.parameterIndex;a===void 0&&c!==void 0&&(console.log(`[Cabbage-React] Received parameterIndex for channelId "${t.id}"`,c),r(c));const m=(u=t.range)==null?void 0:u.defaultValue;s===void 0&&m!==void 0&&(console.log(`[Cabbage-React] Received default value for channelId "${t.id}"`,m),n(m))},[e]),l.useEffect(()=>{const t=c=>{var u;const{command:m}=c.data;if(m==="parameterChange"){const{value:d,paramIdx:b}=c.data.data;if(b!==a||d===null)return;console.log(`[Cabbage-React] Received parameterChange for parameterIndex ${b}`,d),n(d)}else if(m==="batchWidgetUpdate"){const d=c.data.widgets,b=d==null?void 0:d.find(f=>f.id===i);if(!b)return;const w=JSON.parse(b.widgetJson).channels.find(f=>f.id===i),M=(u=w==null?void 0:w.range)==null?void 0:u.value;console.log(`[Cabbage-React] Received batch widget update for channelId ${b.id}`,M),n(M)}};return window.addEventListener("message",t),()=>{window.removeEventListener("message",t)}},[a]),{value:s,setValue:g}},U=i=>{const[o,e]=l.useState();return l.useEffect(()=>{const s=n=>{const{widgetJson:a,command:r}=n.data;if(a&&r==="widgetUpdate"){const g=JSON.parse(a);if(g.id!==i)return;console.log(`[Cabbage-React] Received message for channelId ${g.id}`,g),e(g)}};return window.addEventListener("message",s),()=>{window.removeEventListener("message",s)}},[]),{message:o}};exports.Cabbage=p;exports.useCabbageMessage=U;exports.useCabbageProperties=C;exports.useCabbageState=I;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { useCabbageState } from './hooks/useCabbageState';
2
2
  export { useCabbageProperties } from './hooks/useCabbageProperties';
3
+ export { useCabbageMessage } from './hooks/useCabbageMessage';
3
4
  export { Cabbage } from './cabbage/cabbage';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { useState as u, useEffect as M } from "react";
1
+ import { useState as f, useEffect as b } from "react";
2
2
  console.log("Cabbage: loading cabbage.js");
3
- class I {
3
+ class C {
4
4
  /**
5
5
  * Send a widget value change to the Cabbage backend.
6
6
  *
@@ -21,16 +21,16 @@ class I {
21
21
  * @param {string} [data.gesture="complete"] - The gesture type: "begin" (start of interaction), "value" (during interaction), "end" (end of continuous interaction), or "complete" (discrete action e.g. button click).
22
22
  * @param {Object|null} vscode - VS Code API object (null for plugin mode)
23
23
  */
24
- static sendControlData({ channel: o, value: e, gesture: s = "complete" }, a = null) {
25
- const n = {
24
+ static sendControlData({ channel: o, value: e, gesture: s = "complete" }, n = null) {
25
+ const a = {
26
26
  command: "controlData",
27
27
  channel: o,
28
28
  value: e,
29
29
  gesture: s
30
30
  };
31
- a !== null ? a.postMessage(n) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(n) : console.error(
31
+ n !== null ? n.postMessage(a) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(a) : console.error(
32
32
  "Cabbage: window.sendMessageFromUI is not available. Message:",
33
- n
33
+ a
34
34
  );
35
35
  }
36
36
  /**
@@ -50,19 +50,19 @@ class I {
50
50
  * @param {number} dataByte2 - Second MIDI data byte
51
51
  * @param {Object|null} vscode - VS Code API object (null for plugin mode)
52
52
  */
53
- static sendMidiMessageFromUI(o, e, s, a = null) {
54
- var n = {
53
+ static sendMidiMessageFromUI(o, e, s, n = null) {
54
+ var a = {
55
55
  statusByte: o,
56
56
  dataByte1: e,
57
57
  dataByte2: s
58
58
  };
59
- const d = {
59
+ const r = {
60
60
  command: "midiMessage",
61
- obj: JSON.stringify(n)
61
+ obj: JSON.stringify(a)
62
62
  };
63
- a !== null ? a.postMessage(d) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(d) : console.error(
63
+ n !== null ? n.postMessage(r) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(r) : console.error(
64
64
  "Cabbage: window.sendMessageFromUI is not available. Message:",
65
- d
65
+ r
66
66
  );
67
67
  }
68
68
  /**
@@ -88,19 +88,19 @@ class I {
88
88
  * @param {boolean} [options.openAtLastKnownLocation=true] - Whether to open at last known location
89
89
  */
90
90
  static triggerFileOpenDialog(o, e, s = {}) {
91
- var a = {
91
+ var n = {
92
92
  channel: e,
93
93
  directory: s.directory || "",
94
94
  filters: s.filters || "*",
95
95
  openAtLastKnownLocation: s.openAtLastKnownLocation !== void 0 ? s.openAtLastKnownLocation : !0
96
96
  };
97
- const n = {
97
+ const a = {
98
98
  command: "fileOpen",
99
- obj: JSON.stringify(a)
99
+ obj: JSON.stringify(n)
100
100
  };
101
- o !== null ? o.postMessage(n) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(n) : console.error(
101
+ o !== null ? o.postMessage(a) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(a) : console.error(
102
102
  "Cabbage: window.sendMessageFromUI is not available. Message:",
103
- n
103
+ a
104
104
  );
105
105
  }
106
106
  /**
@@ -111,17 +111,17 @@ class I {
111
111
  * @param {string} file - File path to open
112
112
  */
113
113
  static openUrl(o, e, s) {
114
- var a = {
114
+ var n = {
115
115
  url: e,
116
116
  file: s
117
117
  };
118
- const n = {
118
+ const a = {
119
119
  command: "openUrl",
120
- obj: JSON.stringify(a)
120
+ obj: JSON.stringify(n)
121
121
  };
122
- o !== null ? o.postMessage(n) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(n) : console.error(
122
+ o !== null ? o.postMessage(a) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(a) : console.error(
123
123
  "Cabbage: window.sendMessageFromUI is not available. Message:",
124
- n
124
+ a
125
125
  );
126
126
  }
127
127
  /**
@@ -137,7 +137,7 @@ class I {
137
137
  * {command: "resizeResponse", accepted: boolean, width: number, height: number}
138
138
  */
139
139
  static requestResize(o, e, s = null) {
140
- const a = {
140
+ const n = {
141
141
  command: "requestResize",
142
142
  width: o,
143
143
  height: e
@@ -148,9 +148,9 @@ class I {
148
148
  );
149
149
  return;
150
150
  } else
151
- typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(a) : console.error(
151
+ typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(n) : console.error(
152
152
  "Cabbage: window.sendMessageFromUI is not available. Message:",
153
- a
153
+ n
154
154
  );
155
155
  }
156
156
  /**
@@ -161,13 +161,13 @@ class I {
161
161
  * @param {Object|null} vscode - VS Code API object (null for plugin mode)
162
162
  */
163
163
  static sendChannelData(o, e, s = null) {
164
- var a = {
164
+ var n = {
165
165
  channel: o
166
166
  };
167
167
  if (typeof e == "string")
168
- a.stringData = e;
168
+ n.stringData = e;
169
169
  else if (typeof e == "number")
170
- a.floatData = e;
170
+ n.floatData = e;
171
171
  else {
172
172
  console.warn(
173
173
  "Cabbage: sendChannelData received unsupported data type:",
@@ -175,13 +175,13 @@ class I {
175
175
  );
176
176
  return;
177
177
  }
178
- const n = {
178
+ const a = {
179
179
  command: "channelData",
180
- obj: JSON.stringify(a)
180
+ obj: JSON.stringify(n)
181
181
  };
182
- console.log("Cabbage: sending channel data from UI", a), s !== null ? s.postMessage(n) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(n) : console.error(
182
+ console.log("Cabbage: sending channel data from UI", n), s !== null ? s.postMessage(a) : typeof window.sendMessageFromUI == "function" ? window.sendMessageFromUI(a) : console.error(
183
183
  "Cabbage: window.sendMessageFromUI is not available. Message:",
184
- n
184
+ a
185
185
  );
186
186
  }
187
187
  /**
@@ -209,24 +209,24 @@ class I {
209
209
  * @param {Object} additionalData - Additional data to include in the command
210
210
  */
211
211
  static sendCustomCommand(o, e = null, s = {}) {
212
- const a = {
212
+ const n = {
213
213
  command: o,
214
214
  text: JSON.stringify(s)
215
215
  };
216
216
  if (e !== null)
217
- e.postMessage(a);
217
+ e.postMessage(n);
218
218
  else if (typeof window.sendMessageFromUI == "function") {
219
- console.log("Cabbage: Calling window.sendMessageFromUI with:", a);
219
+ console.log("Cabbage: Calling window.sendMessageFromUI with:", n);
220
220
  try {
221
- const n = window.sendMessageFromUI(a);
222
- console.log("Cabbage: sendMessageFromUI returned:", n);
223
- } catch (n) {
224
- console.error("Cabbage: sendMessageFromUI threw error:", n), console.error("Cabbage: Error stack:", n.stack);
221
+ const a = window.sendMessageFromUI(n);
222
+ console.log("Cabbage: sendMessageFromUI returned:", a);
223
+ } catch (a) {
224
+ console.error("Cabbage: sendMessageFromUI threw error:", a), console.error("Cabbage: Error stack:", a.stack);
225
225
  }
226
226
  } else
227
227
  console.error(
228
228
  "Cabbage: window.sendMessageFromUI is not available yet. Message:",
229
- a
229
+ n
230
230
  ), console.error(
231
231
  "Cabbage: typeof window.sendMessageFromUI:",
232
232
  typeof window.sendMessageFromUI
@@ -236,15 +236,15 @@ class I {
236
236
  );
237
237
  }
238
238
  }
239
- const C = (r) => {
240
- const [o, e] = u();
241
- return M(() => {
242
- const s = (a) => {
243
- const { id: n, widgetJson: d, command: w } = a.data;
244
- if (n === r && d && w === "widgetUpdate") {
245
- const t = JSON.parse(d);
239
+ const I = (i) => {
240
+ const [o, e] = f();
241
+ return b(() => {
242
+ const s = (n) => {
243
+ const { id: a, widgetJson: r, command: l } = n.data;
244
+ if (a === i && r && l === "widgetUpdate") {
245
+ const t = JSON.parse(r);
246
246
  console.log(
247
- `[Cabbage-React] Received properties for channelId ${n}`,
247
+ `[Cabbage-React] Received properties for channelId ${a}`,
248
248
  t
249
249
  ), e(t);
250
250
  }
@@ -255,63 +255,84 @@ const C = (r) => {
255
255
  }, []), {
256
256
  properties: o
257
257
  };
258
- }, y = (r, o = "complete") => {
259
- const { properties: e } = C(r), [s, a] = u(), [n, d] = u(), w = (t) => {
260
- a(t), I.sendControlData({
261
- channel: r,
258
+ }, v = (i, o = "complete") => {
259
+ const { properties: e } = I(i), [s, n] = f(), [a, r] = f(), l = (t) => {
260
+ n(t), C.sendControlData({
261
+ channel: i,
262
262
  value: t,
263
263
  gesture: o
264
264
  });
265
265
  };
266
- return M(() => {
267
- var m;
266
+ return b(() => {
267
+ var w;
268
268
  const t = e == null ? void 0 : e.channels.find(
269
- (i) => i.id === r
269
+ (d) => d.id === i
270
270
  );
271
271
  if (!t) return;
272
- const l = t == null ? void 0 : t.parameterIndex;
273
- n === void 0 && l !== void 0 && (console.log(
272
+ const g = t == null ? void 0 : t.parameterIndex;
273
+ a === void 0 && g !== void 0 && (console.log(
274
274
  `[Cabbage-React] Received parameterIndex for channelId "${t.id}"`,
275
- l
276
- ), d(l));
277
- const g = (m = t.range) == null ? void 0 : m.defaultValue;
278
- s === void 0 && g !== void 0 && (console.log(
279
- `[Cabbage-React] Received default value for channelId "${t.id}"`,
280
275
  g
281
- ), a(g));
282
- }, [e]), M(() => {
283
- const t = (l) => {
284
- var m;
285
- const { command: g } = l.data;
286
- if (g === "parameterChange") {
287
- const { value: i, paramIdx: c } = l.data.data;
288
- if (c !== n || i === null) return;
276
+ ), r(g));
277
+ const c = (w = t.range) == null ? void 0 : w.defaultValue;
278
+ s === void 0 && c !== void 0 && (console.log(
279
+ `[Cabbage-React] Received default value for channelId "${t.id}"`,
280
+ c
281
+ ), n(c));
282
+ }, [e]), b(() => {
283
+ const t = (g) => {
284
+ var w;
285
+ const { command: c } = g.data;
286
+ if (c === "parameterChange") {
287
+ const { value: d, paramIdx: m } = g.data.data;
288
+ if (m !== a || d === null) return;
289
289
  console.log(
290
- `[Cabbage-React] Received parameterChange for parameterIndex ${c}`,
291
- i
292
- ), a(i);
293
- } else if (g === "batchWidgetUpdate") {
294
- const i = l.data.widgets, c = i == null ? void 0 : i.find((b) => b.id === r);
295
- if (!c) return;
296
- const f = JSON.parse(c.widgetJson).channels.find(
297
- (b) => b.id === r
298
- ), p = (m = f == null ? void 0 : f.range) == null ? void 0 : m.value;
290
+ `[Cabbage-React] Received parameterChange for parameterIndex ${m}`,
291
+ d
292
+ ), n(d);
293
+ } else if (c === "batchWidgetUpdate") {
294
+ const d = g.data.widgets, m = d == null ? void 0 : d.find((M) => M.id === i);
295
+ if (!m) return;
296
+ const u = JSON.parse(m.widgetJson).channels.find(
297
+ (M) => M.id === i
298
+ ), p = (w = u == null ? void 0 : u.range) == null ? void 0 : w.value;
299
299
  console.log(
300
- `[Cabbage-React] Received batch widget update for channelId ${c.id}`,
300
+ `[Cabbage-React] Received batch widget update for channelId ${m.id}`,
301
301
  p
302
- ), a(p);
302
+ ), n(p);
303
303
  }
304
304
  };
305
305
  return window.addEventListener("message", t), () => {
306
306
  window.removeEventListener("message", t);
307
307
  };
308
- }, [n]), {
308
+ }, [a]), {
309
309
  value: s,
310
- setValue: w
310
+ setValue: l
311
+ };
312
+ }, y = (i) => {
313
+ const [o, e] = f();
314
+ return b(() => {
315
+ const s = (n) => {
316
+ const { widgetJson: a, command: r } = n.data;
317
+ if (a && r === "widgetUpdate") {
318
+ const l = JSON.parse(a);
319
+ if (l.id !== i) return;
320
+ console.log(
321
+ `[Cabbage-React] Received message for channelId ${l.id}`,
322
+ l
323
+ ), e(l);
324
+ }
325
+ };
326
+ return window.addEventListener("message", s), () => {
327
+ window.removeEventListener("message", s);
328
+ };
329
+ }, []), {
330
+ message: o
311
331
  };
312
332
  };
313
333
  export {
314
- I as Cabbage,
315
- C as useCabbageProperties,
316
- y as useCabbageState
334
+ C as Cabbage,
335
+ y as useCabbageMessage,
336
+ I as useCabbageProperties,
337
+ v as useCabbageState
317
338
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabbage-react",
3
- "version": "1.0.30",
3
+ "version": "1.0.32",
4
4
  "type": "module",
5
5
  "keywords": [
6
6
  "cabbage",