@codenotch/codenotch.react 1.0.82 → 2.0.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.
@@ -1,3 +1,4 @@
1
+ import type { ReactNode } from "react";
1
2
  import { ProjectManifest, IAppManifest } from "@codenotch/codenotch.core";
2
3
  import { ICodenotchSignal, IDisposable } from "./Misc";
3
4
  /**
@@ -119,7 +120,11 @@ export interface IProcessResult<T = any> {
119
120
  errorMessage: string;
120
121
  }
121
122
  /**
122
- * The Codenotch client API, obtained by calling `useCodenotch()`.
123
+ * The Codenotch client API.
124
+ *
125
+ * Obtained with the `useCodenotch()` hook in function components, through the
126
+ * `cn` prop injected by `withCodenotch()` in class components, or with the
127
+ * plain `getCodenotch()` function anywhere else (handlers, modules, services).
123
128
  *
124
129
  * It is the bridge between a React app and the Codenotch runtime: it starts
125
130
  * server-side BPMN processes, runs CNQL queries, translates i18n keys,
@@ -196,7 +201,7 @@ export interface ICodenotchApi {
196
201
  * </div>
197
202
  * );
198
203
  */
199
- readonly showDialog: (node: JSX.Element) => ICodenotchDialog;
204
+ readonly showDialog: (node: ReactNode) => ICodenotchDialog;
200
205
  /**
201
206
  * Fetch the text content of a file of the deployed Codenotch project.
202
207
  * @param relativePath Path of the file relative to the project root (e.g. `'readme.md'`).
@@ -243,6 +248,19 @@ export interface ICodenotchApi {
243
248
  /** Manifest of the current application, if any. */
244
249
  readonly getAppManifest: () => IAppManifest | undefined;
245
250
  }
251
+ /**
252
+ * Props injected by the `withCodenotch()` higher-order component.
253
+ * Extend it in the props of a class component wrapped by `withCodenotch`.
254
+ *
255
+ * @example
256
+ * interface Props extends WithCodenotchProps { userId: string }
257
+ * class TodoList extends React.Component<Props> { ... }
258
+ * export default withCodenotch(TodoList);
259
+ */
260
+ export interface WithCodenotchProps {
261
+ /** The Codenotch client API; refreshed (new reference) whenever the environment changes. */
262
+ cn: ICodenotchApi;
263
+ }
246
264
  /**
247
265
  * Handle on a dialog opened with {@link ICodenotchApi.showDialog}.
248
266
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Codenotch.d.ts","sourceRoot":"","sources":["../../src/models/Codenotch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Codenotch.d.ts","sourceRoot":"","sources":["../../src/models/Codenotch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,44 +1,46 @@
1
- {
2
- "name": "@codenotch/codenotch.react",
3
- "version": "1.0.82",
4
- "description": "React bindings for Codenotch applications: start BPMN processes, run cnql queries, translate i18n keys, listen to real-time signals, manage theme and language.",
5
- "keywords": [
6
- "codenotch",
7
- "react"
8
- ],
9
- "publishConfig": {
10
- "access": "public"
11
- },
12
- "homepage": "https://codenotch.com",
13
- "main": "dist/index.js",
14
- "types": "dist/index.d.ts",
15
- "author": "Codenotch SA",
16
- "license": "MIT",
17
- "scripts": {
18
- "build": "tsc",
19
- "dev": "tsc --watch",
20
- "prepublishOnly": "npm run build",
21
- "clean": "rm -rf dist"
22
- },
23
- "files": [
24
- "dist/**/*",
25
- "src/**/*"
26
- ],
27
- "dependencies": {
28
- "@codenotch/codenotch.core": "1.0.21",
29
- "@microsoft/signalr": "^5.0.6",
30
- "uuid": "^8.2.0"
31
- },
32
- "devDependencies": {
33
- "@types/node": "^25.3.2",
34
- "@types/react": "^16.14.69",
35
- "@types/react-dom": "^16.9.25",
36
- "@types/uuid": "8.0.0",
37
- "@types/json-schema": "^7.0.6",
38
- "react-dom": "^16.14.0",
39
- "typescript": "^5.9.3"
40
- },
41
- "peerDependencies": {
42
- "react": ">=16.0.0"
43
- }
44
- }
1
+ {
2
+ "name": "@codenotch/codenotch.react",
3
+ "version": "2.0.0",
4
+ "description": "React bindings for Codenotch applications: start BPMN processes, run cnql queries, translate i18n keys, listen to real-time signals, manage theme and language.",
5
+ "keywords": [
6
+ "codenotch",
7
+ "react"
8
+ ],
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "homepage": "https://codenotch.com",
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "author": "Codenotch SA",
16
+ "license": "MIT",
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "dev": "tsc --watch",
20
+ "prepublishOnly": "npm run build",
21
+ "clean": "rm -rf dist"
22
+ },
23
+ "files": [
24
+ "dist/**/*",
25
+ "src/**/*"
26
+ ],
27
+ "dependencies": {
28
+ "@codenotch/codenotch.core": "1.0.21",
29
+ "@microsoft/signalr": "^5.0.6",
30
+ "uuid": "^8.2.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^25.3.2",
34
+ "@types/react": "^19.1.0",
35
+ "@types/react-dom": "^19.1.0",
36
+ "@types/uuid": "8.0.0",
37
+ "@types/json-schema": "^7.0.6",
38
+ "react": "^19.1.0",
39
+ "react-dom": "^19.1.0",
40
+ "typescript": "^5.9.3"
41
+ },
42
+ "peerDependencies": {
43
+ "react": ">=19.0.0",
44
+ "react-dom": ">=19.0.0"
45
+ }
46
+ }
@@ -1,203 +1,204 @@
1
- import React from "react";
2
- import { ICodenotchEnv } from "..";
3
-
4
- interface ICodeEditorProps {
5
- /** Codenotch environment; only used to follow the current theme (`vs`/`vs-dark`). */
6
- env?: ICodenotchEnv;
7
- style?: React.CSSProperties;
8
- className?: string;
9
- /** Text content of the editor. */
10
- value?: string;
11
- /** Monaco language id (e.g. `'typescript'`, `'json'`, `'xml'`). Defaults to `'plaintext'`. */
12
- language?: string;
13
- readOnly?: boolean;
14
- /** Called (debounced, 300 ms) when the user edits the content. */
15
- onChange?: (value: string) => void;
16
- }
17
-
18
- /**
19
- * Light Monaco code editor embedded in a sandboxed iframe
20
- * (Monaco is loaded from the jsdelivr CDN — requires network access).
21
- *
22
- * @example
23
- * <CodeEditor env={cn.env} language="json" value={text} onChange={setText} />
24
- */
25
- export default class CodeEditor extends React.Component<ICodeEditorProps> {
26
- private isIframeReady = false;
27
- private onChangeTimeoutHandle: any = null;
28
- private onMessageHandler: any;
29
- refFrame = React.createRef<HTMLIFrameElement>();
30
-
31
- constructor(props: ICodeEditorProps) {
32
- super(props);
33
- this.onMessageHandler = this.handleMessage.bind(this);
34
- }
35
-
36
- setValue(value: string) {
37
- if (this.isIframeReady) {
38
- this.postToIframe({
39
- type: 'update',
40
- value: value,
41
- });
42
- }
43
- }
44
-
45
- componentDidMount(): void {
46
- window.addEventListener('message', this.onMessageHandler);
47
- this.writeIframe();
48
- }
49
-
50
- componentWillUnmount(): void {
51
- window.removeEventListener('message', this.onMessageHandler);
52
- }
53
-
54
- componentDidUpdate(prevProps: ICodeEditorProps): void {
55
- const changed = (
56
- prevProps.value !== this.props.value ||
57
- prevProps.language !== this.props.language ||
58
- prevProps.readOnly !== this.props.readOnly
59
- );
60
-
61
- if (changed && this.isIframeReady) {
62
- let isDark = this.props.env?.theme === 'dark';
63
- this.postToIframe({
64
- type: 'update',
65
- value: this.props.value ?? '',
66
- language: this.props.language || 'plaintext',
67
- readOnly: !!this.props.readOnly,
68
- theme: isDark ? 'vs-dark' : 'vs'
69
- });
70
- }
71
-
72
- }
73
-
74
- private handleMessage(event: MessageEvent) {
75
- const data = event.data as any;
76
- if (!data || typeof data !== 'object') return;
77
- if (data.__from !== 'MonacoIframe') return;
78
-
79
- switch (data.type) {
80
- case 'ready': {
81
- this.isIframeReady = true;
82
- // send initial payload
83
- this.postToIframe({
84
- type: 'init',
85
- value: this.props.value ?? '',
86
- language: this.props.language || 'plaintext',
87
- readOnly: !!this.props.readOnly,
88
- theme: this.props.env?.theme === 'dark' ? 'vs-dark' : 'vs'
89
- });
90
- break;
91
- }
92
- case 'change': {
93
- const next = String(data.value ?? '');
94
- if (this.onChangeTimeoutHandle) {
95
- clearTimeout(this.onChangeTimeoutHandle);
96
- }
97
- this.onChangeTimeoutHandle = setTimeout(() => {
98
- this.props.onChange?.(next);
99
- }, 300);
100
- break;
101
- }
102
- }
103
- };
104
-
105
-
106
- private postToIframe(message: any) {
107
- const w = this.refFrame.current?.contentWindow;
108
- if (!w) return;
109
- w.postMessage({ __from: 'MonacoIframe', ...message }, '*');
110
- }
111
-
112
- private writeIframe() {
113
- const iframe = this.refFrame.current;
114
- if (!iframe) return;
115
-
116
- const vsBase = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs';
117
- const html = `<!DOCTYPE html>
118
- <html>
119
- <head>
120
- <meta charset="utf-8" />
121
- <meta name="viewport" content="width=device-width, initial-scale=1" />
122
- <style>
123
- html, body, #container { height: 100%; width: 100%; margin: 0; padding: 0; overflow: hidden; }
124
- </style>
125
- <script>
126
- (function(){
127
- var vsBase = ${JSON.stringify(vsBase)};
128
- // AMD loader
129
- var s = document.createElement('script');
130
- s.src = vsBase + '/loader.js';
131
- s.onload = function(){
132
- // Configure and load monaco
133
- window.require.config({ paths: { vs: vsBase } });
134
- window.require(['vs/editor/editor.main'], function(){
135
- var editor;
136
-
137
- function post(msg){ parent.postMessage(Object.assign({__from:'MonacoIframe'}, msg), '*'); }
138
-
139
- function ensureEditor(){
140
- if (editor) return editor;
141
- editor = monaco.editor.create(document.getElementById('container'), {
142
- value: '',
143
- language: 'plaintext',
144
- theme: 'vs',
145
- automaticLayout: true,
146
- minimap: { enabled: false },
147
- scrollBeyondLastLine: true,
148
- wordWrap: "on"
149
- });
150
- editor.onDidChangeModelContent(function(){
151
- var v = editor.getValue();
152
- post({ type: 'change', value: v });
153
- });
154
- return editor;
155
- }
156
-
157
- window.addEventListener('message', function(ev){
158
- var data = ev.data || {}; if (data.__from !== 'MonacoIframe') return;
159
- if (data.type === 'init' || data.type === 'update'){
160
- var ed = ensureEditor();
161
- if (typeof data.value === 'string' && ed.getValue() !== data.value){ ed.setValue(data.value); }
162
- if (typeof data.language === 'string') { monaco.editor.setModelLanguage(ed.getModel(), data.language); }
163
- if (typeof data.theme === 'string') { monaco.editor.setTheme(data.theme); }
164
- if (typeof data.readOnly === 'boolean') { ed.updateOptions({ readOnly: data.readOnly }); }
165
- }
166
- });
167
-
168
- // Signal ready after monaco is loaded
169
- post({ type: 'ready' });
170
- });
171
- };
172
- document.head.appendChild(s);
173
- })();
174
- </script>
175
- </head>
176
- <body>
177
- <div id="container"></div>
178
- </body>
179
- </html>`;
180
-
181
- const doc = iframe.contentWindow?.document;
182
- if (!doc) return;
183
- doc.open();
184
- doc.write(html);
185
- doc.close();
186
- }
187
-
188
- render() {
189
- let style = this.props.style || {};
190
- style.width = style.width || '100%';
191
- style.height = style.height || '100%';
192
- style.border = style.border || '0';
193
- style.outline = style.outline || '0';
194
-
195
- return <iframe
196
- style={style}
197
- title="Codenotch"
198
- ref={this.refFrame}
199
- className={this.props.className}
200
- sandbox="allow-scripts allow-same-origin"
201
- />
202
- }
203
- }
1
+ import React from "react";
2
+ import { ICodenotchEnv } from "..";
3
+
4
+ interface ICodeEditorProps {
5
+ /** Codenotch environment; only used to follow the current theme (`vs`/`vs-dark`). */
6
+ env?: ICodenotchEnv;
7
+ style?: React.CSSProperties;
8
+ className?: string;
9
+ /** Text content of the editor. */
10
+ value?: string;
11
+ /** Monaco language id (e.g. `'typescript'`, `'json'`, `'xml'`). Defaults to `'plaintext'`. */
12
+ language?: string;
13
+ readOnly?: boolean;
14
+ /** Called (debounced, 300 ms) when the user edits the content. */
15
+ onChange?: (value: string) => void;
16
+ }
17
+
18
+ /**
19
+ * Light Monaco code editor embedded in a sandboxed iframe
20
+ * (Monaco is loaded from the jsdelivr CDN — requires network access).
21
+ *
22
+ * @example
23
+ * <CodeEditor env={cn.env} language="json" value={text} onChange={setText} />
24
+ */
25
+ export default class CodeEditor extends React.Component<ICodeEditorProps> {
26
+ private isIframeReady = false;
27
+ private onChangeTimeoutHandle: any = null;
28
+ private onMessageHandler: any;
29
+ refFrame = React.createRef<HTMLIFrameElement>();
30
+
31
+ constructor(props: ICodeEditorProps) {
32
+ super(props);
33
+ this.onMessageHandler = this.handleMessage.bind(this);
34
+ }
35
+
36
+ setValue(value: string) {
37
+ if (this.isIframeReady) {
38
+ this.postToIframe({
39
+ type: 'update',
40
+ value: value,
41
+ });
42
+ }
43
+ }
44
+
45
+ componentDidMount(): void {
46
+ window.addEventListener('message', this.onMessageHandler);
47
+ this.writeIframe();
48
+ }
49
+
50
+ componentWillUnmount(): void {
51
+ window.removeEventListener('message', this.onMessageHandler);
52
+ }
53
+
54
+ componentDidUpdate(prevProps: ICodeEditorProps): void {
55
+ const changed = (
56
+ prevProps.value !== this.props.value ||
57
+ prevProps.language !== this.props.language ||
58
+ prevProps.readOnly !== this.props.readOnly
59
+ );
60
+
61
+ if (changed && this.isIframeReady) {
62
+ let isDark = this.props.env?.theme === 'dark';
63
+ this.postToIframe({
64
+ type: 'update',
65
+ value: this.props.value ?? '',
66
+ language: this.props.language || 'plaintext',
67
+ readOnly: !!this.props.readOnly,
68
+ theme: isDark ? 'vs-dark' : 'vs'
69
+ });
70
+ }
71
+
72
+ }
73
+
74
+ private handleMessage(event: MessageEvent) {
75
+ const data = event.data as any;
76
+ if (!data || typeof data !== 'object') return;
77
+ if (data.__from !== 'MonacoIframe') return;
78
+
79
+ switch (data.type) {
80
+ case 'ready': {
81
+ this.isIframeReady = true;
82
+ // send initial payload
83
+ this.postToIframe({
84
+ type: 'init',
85
+ value: this.props.value ?? '',
86
+ language: this.props.language || 'plaintext',
87
+ readOnly: !!this.props.readOnly,
88
+ theme: this.props.env?.theme === 'dark' ? 'vs-dark' : 'vs'
89
+ });
90
+ break;
91
+ }
92
+ case 'change': {
93
+ const next = String(data.value ?? '');
94
+ if (this.onChangeTimeoutHandle) {
95
+ clearTimeout(this.onChangeTimeoutHandle);
96
+ }
97
+ this.onChangeTimeoutHandle = setTimeout(() => {
98
+ this.props.onChange?.(next);
99
+ }, 300);
100
+ break;
101
+ }
102
+ }
103
+ };
104
+
105
+
106
+ private postToIframe(message: any) {
107
+ const w = this.refFrame.current?.contentWindow;
108
+ if (!w) return;
109
+ w.postMessage({ __from: 'MonacoIframe', ...message }, '*');
110
+ }
111
+
112
+ private writeIframe() {
113
+ const iframe = this.refFrame.current;
114
+ if (!iframe) return;
115
+
116
+ const vsBase = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs';
117
+ const html = `<!DOCTYPE html>
118
+ <html>
119
+ <head>
120
+ <meta charset="utf-8" />
121
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
122
+ <style>
123
+ html, body, #container { height: 100%; width: 100%; margin: 0; padding: 0; overflow: hidden; }
124
+ </style>
125
+ <script>
126
+ (function(){
127
+ var vsBase = ${JSON.stringify(vsBase)};
128
+ // AMD loader
129
+ var s = document.createElement('script');
130
+ s.src = vsBase + '/loader.js';
131
+ s.onload = function(){
132
+ // Configure and load monaco
133
+ window.require.config({ paths: { vs: vsBase } });
134
+ window.require(['vs/editor/editor.main'], function(){
135
+ var editor;
136
+
137
+ function post(msg){ parent.postMessage(Object.assign({__from:'MonacoIframe'}, msg), '*'); }
138
+
139
+ function ensureEditor(){
140
+ if (editor) return editor;
141
+ editor = monaco.editor.create(document.getElementById('container'), {
142
+ value: '',
143
+ language: 'plaintext',
144
+ theme: 'vs',
145
+ automaticLayout: true,
146
+ minimap: { enabled: false },
147
+ scrollBeyondLastLine: true,
148
+ wordWrap: "on"
149
+ });
150
+ editor.onDidChangeModelContent(function(){
151
+ var v = editor.getValue();
152
+ post({ type: 'change', value: v });
153
+ });
154
+ return editor;
155
+ }
156
+
157
+ window.addEventListener('message', function(ev){
158
+ var data = ev.data || {}; if (data.__from !== 'MonacoIframe') return;
159
+ if (data.type === 'init' || data.type === 'update'){
160
+ var ed = ensureEditor();
161
+ if (typeof data.value === 'string' && ed.getValue() !== data.value){ ed.setValue(data.value); }
162
+ if (typeof data.language === 'string') { monaco.editor.setModelLanguage(ed.getModel(), data.language); }
163
+ if (typeof data.theme === 'string') { monaco.editor.setTheme(data.theme); }
164
+ if (typeof data.readOnly === 'boolean') { ed.updateOptions({ readOnly: data.readOnly }); }
165
+ }
166
+ });
167
+
168
+ // Signal ready after monaco is loaded
169
+ post({ type: 'ready' });
170
+ });
171
+ };
172
+ document.head.appendChild(s);
173
+ })();
174
+ </script>
175
+ </head>
176
+ <body>
177
+ <div id="container"></div>
178
+ </body>
179
+ </html>`;
180
+
181
+ const doc = iframe.contentWindow?.document;
182
+ if (!doc) return;
183
+ doc.open();
184
+ doc.write(html);
185
+ doc.close();
186
+ }
187
+
188
+ render() {
189
+ // Never mutate props: copy the style object before applying defaults.
190
+ const style: React.CSSProperties = { ...this.props.style };
191
+ style.width = style.width || '100%';
192
+ style.height = style.height || '100%';
193
+ style.border = style.border || '0';
194
+ style.outline = style.outline || '0';
195
+
196
+ return <iframe
197
+ style={style}
198
+ title="Codenotch"
199
+ ref={this.refFrame}
200
+ className={this.props.className}
201
+ sandbox="allow-scripts allow-same-origin"
202
+ />
203
+ }
204
+ }