docusaurus-live-brython 3.0.0-beta.11 → 3.0.0-beta.4

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.
Files changed (77) hide show
  1. package/README.md +0 -12
  2. package/lib/index.d.ts +7 -0
  3. package/lib/index.js +0 -15
  4. package/lib/theme/CodeBlock/index.jsx +4 -2
  5. package/lib/theme/CodeEditor/Actions/DownloadCode.jsx +2 -2
  6. package/lib/theme/CodeEditor/Actions/Reset.jsx +2 -2
  7. package/lib/theme/CodeEditor/Actions/RunCode.d.ts +1 -1
  8. package/lib/theme/CodeEditor/Actions/RunCode.jsx +2 -2
  9. package/lib/theme/CodeEditor/Actions/ShowRaw.jsx +2 -2
  10. package/lib/theme/CodeEditor/Actions/ShowSyncStatus.jsx +3 -3
  11. package/lib/theme/CodeEditor/BrythonCommunicator.jsx +2 -2
  12. package/lib/theme/CodeEditor/Button/index.d.ts +2 -2
  13. package/lib/theme/CodeEditor/Button/index.jsx +1 -1
  14. package/lib/theme/CodeEditor/CodeHistory/index.jsx +2 -2
  15. package/lib/theme/CodeEditor/Editor/EditorAce.jsx +2 -2
  16. package/lib/theme/CodeEditor/Editor/Header/index.d.ts +1 -1
  17. package/lib/theme/CodeEditor/Editor/Header/index.jsx +6 -6
  18. package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.d.ts +2 -2
  19. package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.jsx +7 -7
  20. package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.d.ts +2 -2
  21. package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.jsx +8 -8
  22. package/lib/theme/CodeEditor/Editor/Result/Graphics/index.d.ts +3 -3
  23. package/lib/theme/CodeEditor/Editor/Result/Graphics/index.jsx +6 -6
  24. package/lib/theme/CodeEditor/Editor/Result/index.d.ts +3 -1
  25. package/lib/theme/CodeEditor/Editor/Result/index.jsx +3 -2
  26. package/lib/theme/CodeEditor/Editor/index.d.ts +1 -1
  27. package/lib/theme/CodeEditor/Editor/index.jsx +11 -11
  28. package/lib/theme/CodeEditor/Editor/utils/saveSvg.js +1 -1
  29. package/lib/theme/CodeEditor/Icon/index.d.ts +2 -2
  30. package/lib/theme/CodeEditor/Icon/index.jsx +1 -1
  31. package/lib/theme/CodeEditor/WithScript/Storage.d.ts +1 -1
  32. package/lib/theme/CodeEditor/WithScript/Store.d.ts +7 -1
  33. package/lib/theme/CodeEditor/WithScript/Store.jsx +235 -2
  34. package/lib/theme/CodeEditor/WithScript/Types.d.ts +0 -1
  35. package/lib/theme/CodeEditor/index.d.ts +3 -3
  36. package/lib/theme/CodeEditor/index.jsx +6 -6
  37. package/lib/types.d.ts +28 -0
  38. package/lib/types.js +1 -0
  39. package/package.json +23 -79
  40. package/src/index.ts +0 -10
  41. package/src/theme/CodeBlock/index.tsx +9 -2
  42. package/src/theme/CodeEditor/Actions/DownloadCode.tsx +2 -2
  43. package/src/theme/CodeEditor/Actions/Reset.tsx +2 -2
  44. package/src/theme/CodeEditor/Actions/RunCode.tsx +3 -3
  45. package/src/theme/CodeEditor/Actions/ShowRaw.tsx +2 -2
  46. package/src/theme/CodeEditor/Actions/ShowSyncStatus.tsx +3 -3
  47. package/src/theme/CodeEditor/BrythonCommunicator.tsx +3 -3
  48. package/src/theme/CodeEditor/Button/index.tsx +3 -3
  49. package/src/theme/CodeEditor/CodeHistory/index.tsx +2 -2
  50. package/src/theme/CodeEditor/Editor/EditorAce.tsx +2 -2
  51. package/src/theme/CodeEditor/Editor/Header/index.tsx +7 -7
  52. package/src/theme/CodeEditor/Editor/Result/Graphics/Canvas.tsx +7 -7
  53. package/src/theme/CodeEditor/Editor/Result/Graphics/Turtle.tsx +8 -8
  54. package/src/theme/CodeEditor/Editor/Result/Graphics/index.tsx +7 -7
  55. package/src/theme/CodeEditor/Editor/Result/index.tsx +6 -2
  56. package/src/theme/CodeEditor/Editor/index.tsx +15 -13
  57. package/src/theme/CodeEditor/Editor/utils/saveSvg.ts +1 -1
  58. package/src/theme/CodeEditor/Editor/utils/svgWithoutAnimations.ts +1 -1
  59. package/src/theme/CodeEditor/Icon/index.tsx +2 -2
  60. package/src/theme/CodeEditor/WithScript/Storage.ts +1 -1
  61. package/src/theme/CodeEditor/WithScript/Store.tsx +269 -3
  62. package/src/theme/CodeEditor/WithScript/Types.ts +0 -1
  63. package/src/theme/CodeEditor/index.tsx +8 -8
  64. package/src/types.ts +29 -0
  65. package/.prettierrc +0 -9
  66. package/lib/theme/CodeEditor/WithScript/createStore.d.ts +0 -2
  67. package/lib/theme/CodeEditor/WithScript/createStore.js +0 -223
  68. package/lib/theme/CodeEditor/hooks/index.d.ts +0 -2
  69. package/lib/theme/CodeEditor/hooks/index.js +0 -2
  70. package/lib/theme/CodeEditor/hooks/useScript.d.ts +0 -4
  71. package/lib/theme/CodeEditor/hooks/useScript.js +0 -10
  72. package/lib/theme/CodeEditor/hooks/useStore.d.ts +0 -2
  73. package/lib/theme/CodeEditor/hooks/useStore.js +0 -4
  74. package/src/theme/CodeEditor/WithScript/createStore.ts +0 -247
  75. package/src/theme/CodeEditor/hooks/index.ts +0 -2
  76. package/src/theme/CodeEditor/hooks/useScript.ts +0 -15
  77. package/src/theme/CodeEditor/hooks/useStore.ts +0 -9
@@ -1,223 +0,0 @@
1
- import { v4 as uuidv4 } from 'uuid';
2
- import { createStorageSlot } from "@docusaurus/theme-common";
3
- import { getStorageScript, syncStorageScript } from "@theme/CodeEditor/WithScript/Storage";
4
- import { checkCanvasOutput, checkGraphicsOutput, checkTurtleOutput, getPreCode, sanitizePyScript } from "@theme/CodeEditor/WithScript/helpers";
5
- import { Status } from "@theme/CodeEditor/WithScript/Types";
6
- import { DOM_ELEMENT_IDS } from "@theme/CodeEditor/constants";
7
- import throttle from 'lodash/throttle';
8
- export const createStore = (props, libDir, syncMaxOnceEvery) => {
9
- const canSave = !!props.id;
10
- const id = props.id || uuidv4();
11
- const codeId = `code.${props.title || props.lang}.${id}`.replace(/(-|\.)/g, '_');
12
- const createdAt = new Date();
13
- const storageKey = `code.${props.title || 'code_block'}.${id}`;
14
- const storage = createStorageSlot(storageKey);
15
- storage.listen((e) => {
16
- if (e.key === storageKey) {
17
- try {
18
- if (e.newValue) {
19
- const script = JSON.parse(e.newValue);
20
- if (new Date(script.updatedAt) > state.updatedAt) {
21
- loadData(storage);
22
- }
23
- }
24
- }
25
- catch (err) {
26
- console.warn(err);
27
- }
28
- }
29
- });
30
- const loadData = (store) => {
31
- setState((s) => ({ ...s, status: canSave ? Status.SYNCING : s.status }));
32
- const script = getStorageScript(store);
33
- const loadedCode = script?.code ? prepareCode(script.code, { codeOnly: true }) : {};
34
- addVersion.cancel();
35
- if (!state.isLoaded) {
36
- setState((s) => ({
37
- ...s,
38
- isLoaded: true,
39
- ...(script || {}),
40
- ...loadedCode,
41
- versions: script?.versions || [],
42
- versionsLoaded: true,
43
- status: canSave ? Status.SUCCESS : s.status
44
- }));
45
- return Status.SUCCESS;
46
- }
47
- if (script) {
48
- setState((s) => ({ ...s, ...script, ...loadedCode, status: canSave ? Status.SUCCESS : s.status, versionsLoaded: true }));
49
- return Status.SUCCESS;
50
- }
51
- setState((s) => ({ ...s, status: canSave ? Status.ERROR : s.status }));
52
- return Status.ERROR;
53
- };
54
- const prepareCode = (raw, config = {}) => {
55
- const { pre, code } = config.codeOnly
56
- ? { pre: getPreCode(state.pristineCode).pre, code: raw }
57
- : getPreCode(raw);
58
- const hasEdits = code !== (config.stateNotInitialized ? getPreCode(props.raw).code : state.pristineCode);
59
- const updatedAt = new Date();
60
- const hasCanvasOutput = checkCanvasOutput(raw);
61
- const hasTurtleOutput = checkTurtleOutput(raw);
62
- const hasGraphicsOutput = checkGraphicsOutput(raw);
63
- if (props.versioned && !config.stateNotInitialized) {
64
- addVersion({ code: code, createdAt: updatedAt, version: state.versions.length + 1 });
65
- }
66
- return {
67
- code: code,
68
- preCode: pre,
69
- hasCanvasOutput: hasCanvasOutput,
70
- hasTurtleOutput: hasTurtleOutput,
71
- hasGraphicsOutput: hasGraphicsOutput,
72
- hasEdits: hasEdits,
73
- updatedAt: updatedAt
74
- };
75
- };
76
- const setCode = (raw, action) => {
77
- if (state.isPasted && action === 'remove') {
78
- return;
79
- }
80
- const data = prepareCode(raw);
81
- setState((state) => ({
82
- ...state,
83
- ...data
84
- }));
85
- if (props.id) {
86
- const toStore = { code: data.code, createdAt: state.createdAt, updatedAt: data.updatedAt, versions: state.versions };
87
- if (state.isPasted) {
88
- addVersion.flush();
89
- if (toStore.versions.length > 0) {
90
- toStore.versions[toStore.versions.length - 1].pasted = true;
91
- }
92
- set(toStore);
93
- set.flush();
94
- state.isPasted = false;
95
- }
96
- else {
97
- set(toStore);
98
- }
99
- }
100
- };
101
- const execScript = () => {
102
- const toExec = `${state.code}`;
103
- const lineShift = state.preCode.split(/\n/).length;
104
- const src = `from brython_runner import run
105
- run("""${sanitizePyScript(toExec || '')}""", '${codeId}', ${lineShift})
106
- `;
107
- if (!window.__BRYTHON__) {
108
- alert('Brython not loaded');
109
- return;
110
- }
111
- setState((s) => ({ ...s, isExecuting: true, isGraphicsmodalOpen: state.hasGraphicsOutput }));
112
- const active = document.getElementById(DOM_ELEMENT_IDS.communicator(state.codeId));
113
- active.setAttribute('data--start-time', `${Date.now()}`);
114
- /**
115
- * ensure that the script is executed after the current event loop.
116
- * Otherwise, the brython script will not be able to access the graphics output.
117
- */
118
- setTimeout(() => {
119
- window.__BRYTHON__.runPythonSource(src, {
120
- pythonpath: [libDir]
121
- });
122
- }, 0);
123
- };
124
- const load = async () => {
125
- return loadData(storage);
126
- };
127
- const _set = async (script) => {
128
- setState((s) => ({ ...s, status: canSave ? Status.SYNCING : s.status }));
129
- if (syncStorageScript(script, storage)) {
130
- setState((s) => ({ ...s, status: canSave ? Status.SUCCESS : s.status }));
131
- return Status.SUCCESS;
132
- }
133
- setState((s) => ({ ...s, status: canSave ? Status.ERROR : s.status }));
134
- return Status.ERROR;
135
- };
136
- const set = throttle(_set, syncMaxOnceEvery, { leading: false, trailing: true });
137
- const _addVersion = (version) => {
138
- if (!props.versioned || !props.id) {
139
- return;
140
- }
141
- const versions = [...state.versions];
142
- versions.push(version);
143
- setState((s) => ({ ...s, versions: versions }));
144
- };
145
- const addVersion = throttle(_addVersion, syncMaxOnceEvery, { leading: false, trailing: true });
146
- const saveNow = async () => {
147
- addVersion.flush();
148
- return set.flush();
149
- };
150
- const del = async () => {
151
- storage.del();
152
- return Status.SUCCESS;
153
- };
154
- const codeData = prepareCode(props.raw, { stateNotInitialized: true });
155
- const setExecuting = (isExecuting) => {
156
- setState((s) => ({ ...s, isExecuting: isExecuting }));
157
- };
158
- const addLogMessage = (log) => {
159
- setState((s) => ({ ...s, logs: [...s.logs, log] }));
160
- };
161
- const clearLogMessages = () => {
162
- setState((s) => ({ ...s, logs: [] }));
163
- };
164
- const closeGraphicsModal = () => {
165
- setState((s) => ({ ...s, isGraphicsmodalOpen: false }));
166
- };
167
- const stopScript = () => {
168
- const code = document.getElementById(DOM_ELEMENT_IDS.communicator(state.codeId));
169
- if (code) {
170
- code.removeAttribute('data--start-time');
171
- }
172
- };
173
- let state = {
174
- id: id,
175
- codeId: codeId,
176
- lang: props.lang,
177
- showRaw: false,
178
- pristineCode: codeData.code,
179
- isExecuting: false,
180
- logs: [],
181
- isGraphicsmodalOpen: false,
182
- hasEdits: false,
183
- createdAt: createdAt,
184
- isLoaded: false,
185
- status: Status.IDLE,
186
- versions: [],
187
- versionsLoaded: false,
188
- isPasted: false,
189
- ...codeData
190
- };
191
- const getState = () => state;
192
- const listeners = new Set();
193
- const setState = (fn) => {
194
- state = fn(state);
195
- listeners.forEach((l) => l());
196
- };
197
- const subscribe = (listener) => {
198
- listeners.add(listener);
199
- return () => listeners.delete(listener);
200
- };
201
- const loadVersions = async () => {
202
- // noop
203
- state.isLoaded = false;
204
- load();
205
- setState((s) => ({ ...s, versionsLoaded: true }));
206
- return Promise.resolve();
207
- };
208
- return {
209
- getState,
210
- setState,
211
- subscribe,
212
- saveNow,
213
- addLogMessage,
214
- clearLogMessages,
215
- closeGraphicsModal,
216
- setCode,
217
- execScript,
218
- setExecuting,
219
- stopScript,
220
- load,
221
- loadVersions
222
- };
223
- };
@@ -1,2 +0,0 @@
1
- export { useScript } from './useScript';
2
- export { useStore } from './useStore';
@@ -1,2 +0,0 @@
1
- export { useScript } from './useScript';
2
- export { useStore } from './useStore';
@@ -1,4 +0,0 @@
1
- import { type Store } from "@theme/CodeEditor/WithScript/Types";
2
- export declare function useScript(): {
3
- store: Store;
4
- };
@@ -1,10 +0,0 @@
1
- import { Context } from "@theme/CodeEditor/WithScript/Store";
2
- import { ReactContextError } from "@docusaurus/theme-common";
3
- import { useContext } from "react";
4
- export function useScript() {
5
- const context = useContext(Context);
6
- if (context === null) {
7
- throw new ReactContextError('ScriptContextProvider', 'The Component must be a child of the ScriptContextProvider component');
8
- }
9
- return context;
10
- }
@@ -1,2 +0,0 @@
1
- import { Selector, type Store } from "@theme/CodeEditor/WithScript/Types";
2
- export declare const useStore: <T, R>(store: Store<T>, selector: Selector<T, R>) => R;
@@ -1,4 +0,0 @@
1
- import { useCallback, useSyncExternalStore } from "react";
2
- export const useStore = (store, selector) => {
3
- return useSyncExternalStore(store.subscribe, useCallback(() => selector(store.getState()), [store, selector]));
4
- };
@@ -1,247 +0,0 @@
1
- import { v4 as uuidv4 } from 'uuid';
2
- import { createStorageSlot } from "@docusaurus/theme-common";
3
- import { getStorageScript, syncStorageScript } from "@theme/CodeEditor/WithScript/Storage";
4
- import { checkCanvasOutput, checkGraphicsOutput, checkTurtleOutput, getPreCode, sanitizePyScript } from "@theme/CodeEditor/WithScript/helpers";
5
- import { type InitState, type LogMessage, type Script, Status, type Store, type StoredScript, type Version } from "@theme/CodeEditor/WithScript/Types";
6
- import { DOM_ELEMENT_IDS } from "@theme/CodeEditor/constants";
7
- import throttle from 'lodash/throttle';
8
-
9
- export const createStore = (props: InitState, libDir: string, syncMaxOnceEvery: number): Store => {
10
- const canSave = !!props.id;
11
- const id = props.id || uuidv4();
12
- const codeId = `code.${props.title || props.lang}.${id}`.replace(/(-|\.)/g, '_');
13
- const createdAt = new Date();
14
- const storageKey = `code.${props.title || 'code_block'}.${id}`;
15
- const storage = createStorageSlot(storageKey);
16
- storage.listen((e) => {
17
- if (e.key === storageKey) {
18
- try {
19
- if (e.newValue) {
20
- const script = JSON.parse(e.newValue) as StoredScript;
21
- if (new Date(script.updatedAt) > state.updatedAt) {
22
- loadData(storage);
23
- }
24
- }
25
- } catch (err) {
26
- console.warn(err);
27
- }
28
- }
29
- });
30
-
31
- const loadData = (store) => {
32
- setState((s) => ({...s, status: canSave ? Status.SYNCING : s.status}));
33
- const script = getStorageScript(store);
34
- const loadedCode = script?.code ? prepareCode(script.code, { codeOnly: true }) : {};
35
- addVersion.cancel();
36
- if (!state.isLoaded) {
37
- setState((s) => ({
38
- ...s,
39
- isLoaded: true,
40
- ...(script || {}),
41
- ...loadedCode,
42
- versions: script?.versions || [],
43
- versionsLoaded: true,
44
- status: canSave ? Status.SUCCESS : s.status
45
- }));
46
- return Status.SUCCESS;
47
- }
48
- if (script) {
49
- setState((s) => ({...s, ...script, ...loadedCode, status: canSave ? Status.SUCCESS : s.status, versionsLoaded: true}));
50
- return Status.SUCCESS;
51
- }
52
- setState((s) => ({...s, status: canSave ? Status.ERROR : s.status}));
53
- return Status.ERROR;
54
- }
55
-
56
-
57
- const prepareCode = (raw: string, config: { codeOnly?: boolean, stateNotInitialized?: boolean } = {}) => {
58
- const { pre, code } = config.codeOnly
59
- ? { pre: getPreCode(state.pristineCode).pre, code: raw }
60
- : getPreCode(raw);
61
- const hasEdits = code !== (config.stateNotInitialized ? getPreCode(props.raw).code : state.pristineCode);
62
- const updatedAt = new Date();
63
- const hasCanvasOutput = checkCanvasOutput(raw);
64
- const hasTurtleOutput = checkTurtleOutput(raw);
65
- const hasGraphicsOutput = checkGraphicsOutput(raw);
66
- if (props.versioned && !config.stateNotInitialized) {
67
- addVersion({code: code, createdAt: updatedAt, version: state.versions.length + 1});
68
- }
69
- return {
70
- code: code,
71
- preCode: pre,
72
- hasCanvasOutput: hasCanvasOutput,
73
- hasTurtleOutput: hasTurtleOutput,
74
- hasGraphicsOutput: hasGraphicsOutput,
75
- hasEdits: hasEdits,
76
- updatedAt: updatedAt
77
- };
78
- }
79
-
80
- const setCode = (raw: string, action?: 'insert' | 'remove' | string) => {
81
- if (state.isPasted && action === 'remove') {
82
- return;
83
- }
84
- const data = prepareCode(raw);
85
- setState(
86
- (state) => ({
87
- ...state,
88
- ...data
89
- })
90
- );
91
- if (props.id) {
92
- const toStore: StoredScript = {code: data.code, createdAt: state.createdAt, updatedAt: data.updatedAt, versions: state.versions};
93
- if (state.isPasted) {
94
- addVersion.flush();
95
- if (toStore.versions.length > 0) {
96
- toStore.versions[toStore.versions.length - 1].pasted = true;
97
- }
98
- set(toStore);
99
- set.flush();
100
- state.isPasted = false;
101
- } else {
102
- set(toStore);
103
- }
104
- }
105
- };
106
-
107
- const execScript = () => {
108
- const toExec = `${state.code}`;
109
- const lineShift = state.preCode.split(/\n/).length;
110
- const src = `from brython_runner import run
111
- run("""${sanitizePyScript(toExec || '')}""", '${codeId}', ${lineShift})
112
- `;
113
- if (!(window as any).__BRYTHON__) {
114
- alert('Brython not loaded');
115
- return;
116
- }
117
- setState((s) => ({...s, isExecuting: true, isGraphicsmodalOpen: state.hasGraphicsOutput}));
118
- const active = document.getElementById(DOM_ELEMENT_IDS.communicator(state.codeId));
119
- active.setAttribute('data--start-time', `${Date.now()}`);
120
- /**
121
- * ensure that the script is executed after the current event loop.
122
- * Otherwise, the brython script will not be able to access the graphics output.
123
- */
124
- setTimeout(() => {
125
- (window as any).__BRYTHON__.runPythonSource(
126
- src,
127
- {
128
- pythonpath: [libDir]
129
- }
130
- );
131
- }, 0);
132
- };
133
- const load = async () => {
134
- return loadData(storage);
135
- };
136
- const _set = async (script: StoredScript) => {
137
- setState((s) => ({...s, status: canSave ? Status.SYNCING : s.status}));
138
- if (syncStorageScript(script, storage)) {
139
- setState((s) => ({...s, status: canSave ? Status.SUCCESS : s.status}));
140
- return Status.SUCCESS;
141
- }
142
- setState((s) => ({...s, status: canSave ? Status.ERROR : s.status}));
143
- return Status.ERROR;
144
- };
145
-
146
- const set = throttle(
147
- _set,
148
- syncMaxOnceEvery,
149
- {leading: false, trailing: true}
150
- );
151
-
152
- const _addVersion = (version: Version) => {
153
- if (!props.versioned || !props.id) {
154
- return;
155
- }
156
- const versions = [...state.versions];
157
- versions.push(version);
158
- setState((s) => ({...s, versions: versions}));
159
- }
160
- const addVersion = throttle(
161
- _addVersion,
162
- syncMaxOnceEvery,
163
- {leading: false, trailing: true}
164
- );
165
-
166
- const saveNow = async () => {
167
- addVersion.flush();
168
- return set.flush();
169
- }
170
-
171
- const del = async () => {
172
- storage.del();
173
- return Status.SUCCESS;
174
- }
175
- const codeData = prepareCode(props.raw, { stateNotInitialized: true });
176
- const setExecuting = (isExecuting: boolean) => {
177
- setState((s) => ({...s, isExecuting: isExecuting}))
178
- };
179
- const addLogMessage = (log: LogMessage) => {
180
- setState((s) => ({...s, logs: [...s.logs, log]}));
181
- };
182
- const clearLogMessages = () => {
183
- setState((s) => ({...s, logs: []}));
184
- };
185
- const closeGraphicsModal = () => {
186
- setState((s) => ({...s, isGraphicsmodalOpen: false}));
187
- };
188
- const stopScript = () => {
189
- const code = document.getElementById(DOM_ELEMENT_IDS.communicator(state.codeId));
190
- if (code) {
191
- code.removeAttribute('data--start-time');
192
- }
193
- };
194
- let state: Script = {
195
- id: id,
196
- codeId: codeId,
197
- lang: props.lang,
198
- showRaw: false,
199
- pristineCode: codeData.code,
200
- isExecuting: false,
201
- logs: [],
202
- isGraphicsmodalOpen: false,
203
- hasEdits: false,
204
- createdAt: createdAt,
205
- isLoaded: false,
206
- status: Status.IDLE,
207
- versions: [],
208
- versionsLoaded: false,
209
- isPasted: false,
210
- ...codeData
211
- };
212
-
213
-
214
- const getState = () => state;
215
- const listeners = new Set<() => void>();
216
- const setState = (fn: (state: Script) => Script) => {
217
- state = fn(state);
218
- listeners.forEach((l) => l());
219
- };
220
- const subscribe = (listener: () => void) => {
221
- listeners.add(listener);
222
- return () => listeners.delete(listener);
223
- };
224
- const loadVersions = async () => {
225
- // noop
226
- state.isLoaded = false;
227
- load();
228
- setState((s) => ({...s, versionsLoaded: true}));
229
- return Promise.resolve();
230
- }
231
-
232
- return {
233
- getState,
234
- setState,
235
- subscribe,
236
- saveNow,
237
- addLogMessage,
238
- clearLogMessages,
239
- closeGraphicsModal,
240
- setCode,
241
- execScript,
242
- setExecuting,
243
- stopScript,
244
- load,
245
- loadVersions
246
- } satisfies Store;
247
- };
@@ -1,2 +0,0 @@
1
- export {useScript} from './useScript';
2
- export {useStore} from './useStore';
@@ -1,15 +0,0 @@
1
- import { Context } from "@theme/CodeEditor/WithScript/Store";
2
- import {type Store } from "@theme/CodeEditor/WithScript/Types";
3
- import { ReactContextError } from "@docusaurus/theme-common";
4
- import { useContext } from "react";
5
-
6
- export function useScript(): {store: Store} {
7
- const context = useContext(Context);
8
- if (context === null) {
9
- throw new ReactContextError(
10
- 'ScriptContextProvider',
11
- 'The Component must be a child of the ScriptContextProvider component',
12
- );
13
- }
14
- return context;
15
- }
@@ -1,9 +0,0 @@
1
- import {Selector, type Store } from "@theme/CodeEditor/WithScript/Types";
2
- import { useCallback, useSyncExternalStore } from "react";
3
-
4
- export const useStore = <T, R>(store: Store<T>, selector: Selector<T, R>): R => {
5
- return useSyncExternalStore(
6
- store.subscribe,
7
- useCallback(() => selector(store.getState()), [store, selector])
8
- );
9
- }