@luna-editor/engine 0.3.0 → 0.3.1
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/dist/Player.js +191 -37
- package/dist/components/BackgroundLayer.js +7 -5
- package/dist/components/GameScreen.d.ts +8 -2
- package/dist/components/GameScreen.js +41 -7
- package/dist/components/OverlayUI.d.ts +2 -3
- package/dist/components/OverlayUI.js +3 -14
- package/dist/components/PluginComponentProvider.d.ts +1 -1
- package/dist/components/PluginComponentProvider.js +20 -2
- package/dist/contexts/DataContext.d.ts +3 -1
- package/dist/contexts/DataContext.js +38 -9
- package/dist/contexts/PlaybackTextContext.d.ts +32 -0
- package/dist/contexts/PlaybackTextContext.js +29 -0
- package/dist/data-api-types.d.ts +251 -0
- package/dist/data-api-types.js +6 -0
- package/dist/emotion-effect-types.d.ts +86 -0
- package/dist/emotion-effect-types.js +6 -0
- package/dist/hooks/useBacklog.js +0 -1
- package/dist/hooks/useFontLoader.d.ts +9 -2
- package/dist/hooks/useFontLoader.js +126 -87
- package/dist/hooks/useImagePreloader.d.ts +5 -0
- package/dist/hooks/useImagePreloader.js +53 -0
- package/dist/hooks/usePluginAPI.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/plugin/PluginManager.d.ts +21 -4
- package/dist/plugin/PluginManager.js +122 -59
- package/dist/plugin/luna-react.d.ts +41 -0
- package/dist/plugin/luna-react.js +99 -0
- package/dist/sdk.d.ts +31 -217
- package/dist/sdk.js +12 -2
- package/dist/types.d.ts +13 -1
- package/package.json +6 -6
|
@@ -21,6 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
21
21
|
import React from "react";
|
|
22
22
|
import { useScreenSizeAtom } from "../atoms/screen-size";
|
|
23
23
|
import { useDataAPI } from "../contexts/DataContext";
|
|
24
|
+
import { getFontFamilyStyle, getUIFontFamilyStyle, } from "../hooks/useFontLoader";
|
|
24
25
|
import { usePluginAPI, useUIVisibility } from "../hooks/usePluginAPI";
|
|
25
26
|
import { useScreenScale, useScreenSize, useToPixel, } from "../hooks/useScreenSize";
|
|
26
27
|
import { ComponentType, definePlugin, } from "../sdk";
|
|
@@ -31,6 +32,7 @@ export class PluginManager {
|
|
|
31
32
|
constructor() {
|
|
32
33
|
this.plugins = new Map();
|
|
33
34
|
this.styleElements = new Map();
|
|
35
|
+
this.originalClassNames = new Map(); // 元のクラス名を保持
|
|
34
36
|
this.injectedStyles = new Set();
|
|
35
37
|
this.storage = new Map();
|
|
36
38
|
this.componentRegistry = new Map();
|
|
@@ -38,6 +40,8 @@ export class PluginManager {
|
|
|
38
40
|
this.uiVisibilityListeners = new Map();
|
|
39
41
|
this.selectChoiceCallback = null;
|
|
40
42
|
this.getBranchStateCallback = null;
|
|
43
|
+
this.emotionEffectUpdaterCallback = null;
|
|
44
|
+
this.dataContextGetter = null;
|
|
41
45
|
this.preloadPromises = [];
|
|
42
46
|
this.muteAudio = false;
|
|
43
47
|
// 作品のサウンドデータ(ID → URL)
|
|
@@ -49,6 +53,18 @@ export class PluginManager {
|
|
|
49
53
|
this.clickSoundOverridden = false;
|
|
50
54
|
this.initializeReactRuntime();
|
|
51
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* 開発環境かどうかを判定
|
|
58
|
+
* localhost、127.0.0.1、またはポート3000で実行されている場合に true を返す
|
|
59
|
+
*/
|
|
60
|
+
isDevelopment() {
|
|
61
|
+
if (typeof window === "undefined") {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return (window.location.hostname === "localhost" ||
|
|
65
|
+
window.location.hostname === "127.0.0.1" ||
|
|
66
|
+
window.location.port === "3000");
|
|
67
|
+
}
|
|
52
68
|
/**
|
|
53
69
|
* グローバルReactランタイムを初期化(クライアントサイドのみ)
|
|
54
70
|
* 既に初期化済みの場合はスキップ
|
|
@@ -92,50 +108,62 @@ export class PluginManager {
|
|
|
92
108
|
useScreenScale,
|
|
93
109
|
useScreenSizeAtom,
|
|
94
110
|
ComponentType,
|
|
95
|
-
definePlugin
|
|
96
|
-
|
|
111
|
+
definePlugin,
|
|
112
|
+
getFontFamilyStyle,
|
|
113
|
+
getUIFontFamilyStyle });
|
|
97
114
|
}
|
|
98
|
-
loadPlugin(packageName, bundleUrl, config) {
|
|
115
|
+
loadPlugin(packageName, bundleUrl, config, assets) {
|
|
99
116
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
//
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
for (const [type, component] of globalLoaded.instance.components) {
|
|
109
|
-
this.componentRegistry.set(type, component);
|
|
110
|
-
}
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
// ローカルに既にロード済みの場合はconfigだけ更新してスキップ
|
|
114
|
-
const localLoaded = this.plugins.get(packageName);
|
|
115
|
-
if (localLoaded) {
|
|
116
|
-
console.log(`Plugin ${packageName} is already loaded, updating config.`);
|
|
117
|
-
// configを更新
|
|
118
|
-
localLoaded.config = config !== null && config !== void 0 ? config : localLoaded.config;
|
|
119
|
-
return;
|
|
117
|
+
// 開発環境ではキャッシュをバイパスして常に最新コードをロード
|
|
118
|
+
const isDevelopment = this.isDevelopment();
|
|
119
|
+
if (isDevelopment) {
|
|
120
|
+
// 開発環境では強制リロード(キャッシュをクリア)
|
|
121
|
+
globalLoadedPlugins.delete(packageName);
|
|
122
|
+
this.plugins.delete(packageName);
|
|
123
|
+
// ロード中のPromiseもクリア(再ロードを確実にするため)
|
|
124
|
+
globalLoadingPlugins.delete(packageName);
|
|
120
125
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (loaded) {
|
|
129
|
-
const updatedPlugin = Object.assign(Object.assign({}, loaded), { config: config !== null && config !== void 0 ? config : loaded.config });
|
|
126
|
+
else {
|
|
127
|
+
// 本番環境のみキャッシュを使用
|
|
128
|
+
// グローバルに既にロード済みの場合はローカルにコピーしてスキップ
|
|
129
|
+
const globalLoaded = globalLoadedPlugins.get(packageName);
|
|
130
|
+
if (globalLoaded) {
|
|
131
|
+
// 新しいconfigで更新したコピーを作成
|
|
132
|
+
const updatedPlugin = Object.assign(Object.assign({}, globalLoaded), { config: config !== null && config !== void 0 ? config : globalLoaded.config });
|
|
130
133
|
this.plugins.set(packageName, updatedPlugin);
|
|
131
|
-
|
|
134
|
+
// コンポーネントレジストリにも登録
|
|
135
|
+
for (const [type, component] of globalLoaded.instance.components) {
|
|
132
136
|
this.componentRegistry.set(type, component);
|
|
133
137
|
}
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (!isDevelopment) {
|
|
142
|
+
// 本番環境のみ:ローカルに既にロード済みの場合はconfigだけ更新してスキップ
|
|
143
|
+
const localLoaded = this.plugins.get(packageName);
|
|
144
|
+
if (localLoaded) {
|
|
145
|
+
// configを更新
|
|
146
|
+
localLoaded.config = config !== null && config !== void 0 ? config : localLoaded.config;
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// 本番環境のみ:グローバルでロード中の場合はそのPromiseを待つ
|
|
150
|
+
const existingLoadPromise = globalLoadingPlugins.get(packageName);
|
|
151
|
+
if (existingLoadPromise) {
|
|
152
|
+
yield existingLoadPromise;
|
|
153
|
+
// ロード完了後にグローバルからコピー(新しいconfigで更新)
|
|
154
|
+
const loaded = globalLoadedPlugins.get(packageName);
|
|
155
|
+
if (loaded) {
|
|
156
|
+
const updatedPlugin = Object.assign(Object.assign({}, loaded), { config: config !== null && config !== void 0 ? config : loaded.config });
|
|
157
|
+
this.plugins.set(packageName, updatedPlugin);
|
|
158
|
+
for (const [type, component] of loaded.instance.components) {
|
|
159
|
+
this.componentRegistry.set(type, component);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return;
|
|
134
163
|
}
|
|
135
|
-
return;
|
|
136
164
|
}
|
|
137
165
|
// ロード処理をPromiseとして保存
|
|
138
|
-
const loadPromise = this.doLoadPlugin(packageName, bundleUrl, config);
|
|
166
|
+
const loadPromise = this.doLoadPlugin(packageName, bundleUrl, config, assets);
|
|
139
167
|
globalLoadingPlugins.set(packageName, loadPromise);
|
|
140
168
|
try {
|
|
141
169
|
yield loadPromise;
|
|
@@ -146,7 +174,7 @@ export class PluginManager {
|
|
|
146
174
|
}
|
|
147
175
|
});
|
|
148
176
|
}
|
|
149
|
-
doLoadPlugin(packageName, bundleUrl, config) {
|
|
177
|
+
doLoadPlugin(packageName, bundleUrl, config, assets) {
|
|
150
178
|
return __awaiter(this, void 0, void 0, function* () {
|
|
151
179
|
try {
|
|
152
180
|
// スクリプトタグで動的にプラグインを読み込む
|
|
@@ -160,11 +188,16 @@ export class PluginManager {
|
|
|
160
188
|
components: new Map(),
|
|
161
189
|
assetUrls: new Map(),
|
|
162
190
|
};
|
|
191
|
+
// 外部アプリから渡されたアセットURLを事前にキャッシュ
|
|
192
|
+
if (assets) {
|
|
193
|
+
for (const asset of assets) {
|
|
194
|
+
instance.assetUrls.set(asset.filename, asset.url);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
163
197
|
// プラグインAPIを作成
|
|
164
198
|
const api = this.createPluginAPI(packageName, instance);
|
|
165
199
|
// プラグインをセットアップ
|
|
166
200
|
plugin.setup(api);
|
|
167
|
-
console.log(`Plugin ${packageName} setup completed. Hooks:`, Object.keys(instance.hooks));
|
|
168
201
|
const loadedPlugin = {
|
|
169
202
|
plugin,
|
|
170
203
|
instance,
|
|
@@ -203,9 +236,7 @@ export class PluginManager {
|
|
|
203
236
|
};
|
|
204
237
|
// プラグインバンドルをfetchで取得して実行
|
|
205
238
|
// 開発環境ではキャッシュを無効化してホットリロードを確実に動作させる
|
|
206
|
-
const isDevelopment =
|
|
207
|
-
window.location.hostname === "127.0.0.1" ||
|
|
208
|
-
window.location.port === "3000";
|
|
239
|
+
const isDevelopment = this.isDevelopment();
|
|
209
240
|
const fetchOptions = isDevelopment
|
|
210
241
|
? {
|
|
211
242
|
cache: "no-cache",
|
|
@@ -215,7 +246,6 @@ export class PluginManager {
|
|
|
215
246
|
},
|
|
216
247
|
}
|
|
217
248
|
: {};
|
|
218
|
-
console.log(`🔄 Loading plugin ${packageName} (dev: ${isDevelopment}, cache: ${isDevelopment ? "disabled" : "enabled"})`);
|
|
219
249
|
fetch(url, fetchOptions)
|
|
220
250
|
.then((response) => {
|
|
221
251
|
if (!response.ok) {
|
|
@@ -589,16 +619,26 @@ export class PluginManager {
|
|
|
589
619
|
preload: (filenames) => {
|
|
590
620
|
const preloadPromise = (() => __awaiter(this, void 0, void 0, function* () {
|
|
591
621
|
const promises = filenames.map((filename) => __awaiter(this, void 0, void 0, function* () {
|
|
592
|
-
// API
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
622
|
+
// 既にキャッシュされたURLがあればAPIフェッチをスキップ
|
|
623
|
+
let finalUrl = instance.assetUrls.get(filename);
|
|
624
|
+
if (!finalUrl) {
|
|
625
|
+
// APIエンドポイントURL
|
|
626
|
+
const encodedPackageName = encodeURIComponent(packageName);
|
|
627
|
+
const encodedFilename = encodeURIComponent(filename);
|
|
628
|
+
const apiUrl = `/api/plugin/${encodedPackageName}/assets/${encodedFilename}`;
|
|
629
|
+
// fetchでリダイレクト後の最終URLを取得
|
|
630
|
+
try {
|
|
631
|
+
const response = yield fetch(apiUrl, { method: "HEAD" });
|
|
632
|
+
finalUrl = response.url; // リダイレクト後の最終URL
|
|
633
|
+
// 最終URLをキャッシュに保存
|
|
634
|
+
instance.assetUrls.set(filename, finalUrl);
|
|
635
|
+
}
|
|
636
|
+
catch (error) {
|
|
637
|
+
console.error(`Failed to preload asset: ${filename}`, error);
|
|
638
|
+
return Promise.resolve();
|
|
639
|
+
}
|
|
640
|
+
}
|
|
597
641
|
try {
|
|
598
|
-
const response = yield fetch(apiUrl, { method: "HEAD" });
|
|
599
|
-
const finalUrl = response.url; // リダイレクト後の最終URL
|
|
600
|
-
// 最終URLをキャッシュに保存
|
|
601
|
-
instance.assetUrls.set(filename, finalUrl);
|
|
602
642
|
// 画像をプリロード
|
|
603
643
|
if (filename.match(/\.(png|jpg|jpeg|gif|webp)$/i)) {
|
|
604
644
|
return new Promise((resolve, reject) => {
|
|
@@ -621,7 +661,6 @@ export class PluginManager {
|
|
|
621
661
|
catch (error) {
|
|
622
662
|
console.error(`Failed to preload asset: ${filename}`, error);
|
|
623
663
|
}
|
|
624
|
-
return Promise.resolve();
|
|
625
664
|
}));
|
|
626
665
|
yield Promise.all(promises);
|
|
627
666
|
}))();
|
|
@@ -679,7 +718,6 @@ export class PluginManager {
|
|
|
679
718
|
}
|
|
680
719
|
instance.components.set(type, component);
|
|
681
720
|
this.componentRegistry.set(type, component);
|
|
682
|
-
console.log(`Plugin ${packageName} registered component: ${type}`);
|
|
683
721
|
},
|
|
684
722
|
};
|
|
685
723
|
const uiAPI = {
|
|
@@ -777,8 +815,14 @@ export class PluginManager {
|
|
|
777
815
|
},
|
|
778
816
|
},
|
|
779
817
|
data: {
|
|
780
|
-
get: () => {
|
|
781
|
-
|
|
818
|
+
get: (key) => {
|
|
819
|
+
if (this.dataContextGetter) {
|
|
820
|
+
const context = this.dataContextGetter();
|
|
821
|
+
const value = context === null || context === void 0 ? void 0 : context[key];
|
|
822
|
+
return value;
|
|
823
|
+
}
|
|
824
|
+
console.warn("DataContext getter is not registered. Make sure to call setDataContextGetter.");
|
|
825
|
+
return undefined;
|
|
782
826
|
},
|
|
783
827
|
subscribe: () => {
|
|
784
828
|
throw new Error("DataAPI.subscribe() can only be called from within DataProvider context");
|
|
@@ -804,13 +848,26 @@ export class PluginManager {
|
|
|
804
848
|
setVolumes: () => {
|
|
805
849
|
throw new Error("DataAPI.setVolumes() can only be called from within DataProvider context");
|
|
806
850
|
},
|
|
851
|
+
updateEmotionEffect: (state) => {
|
|
852
|
+
if (this.emotionEffectUpdaterCallback) {
|
|
853
|
+
this.emotionEffectUpdaterCallback(state);
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
console.warn("updateEmotionEffect callback is not registered. Make sure to call setEmotionEffectUpdaterCallback.");
|
|
857
|
+
}
|
|
858
|
+
},
|
|
807
859
|
},
|
|
808
860
|
};
|
|
809
861
|
}
|
|
810
862
|
applyStyles(elementName, classNames) {
|
|
811
863
|
const element = this.styleElements.get(elementName);
|
|
812
864
|
if (element) {
|
|
813
|
-
|
|
865
|
+
// 元のクラス名を取得し、プラグインから追加されたクラスと結合
|
|
866
|
+
const originalClassName = this.originalClassNames.get(elementName) || "";
|
|
867
|
+
const pluginClassNames = classNames.join(" ");
|
|
868
|
+
element.className = originalClassName
|
|
869
|
+
? `${originalClassName} ${pluginClassNames}`
|
|
870
|
+
: pluginClassNames;
|
|
814
871
|
}
|
|
815
872
|
}
|
|
816
873
|
hideEffect(effectId, instance) {
|
|
@@ -831,17 +888,17 @@ export class PluginManager {
|
|
|
831
888
|
// DOM要素にdata-style-element-name属性を追加
|
|
832
889
|
element.setAttribute("data-style-element-name", name);
|
|
833
890
|
this.styleElements.set(name, element);
|
|
891
|
+
// 元のクラス名を保存(初回登録時のみ)
|
|
892
|
+
if (!this.originalClassNames.has(name)) {
|
|
893
|
+
this.originalClassNames.set(name, element.className);
|
|
894
|
+
}
|
|
834
895
|
}
|
|
835
896
|
// フック呼び出しメソッド
|
|
836
897
|
callHook(hookName, ...args) {
|
|
837
|
-
console.log(`Calling hook: ${hookName}`, args);
|
|
838
|
-
console.log(`Number of plugins: ${this.plugins.size}`);
|
|
839
898
|
this.plugins.forEach((loadedPlugin, packageName) => {
|
|
840
899
|
const { instance, enabled } = loadedPlugin;
|
|
841
|
-
console.log(`Plugin ${packageName}: enabled=${enabled}, has hook=${!!instance.hooks[hookName]}`);
|
|
842
900
|
if (enabled && instance.hooks[hookName]) {
|
|
843
901
|
try {
|
|
844
|
-
console.log(`Executing hook ${hookName} for plugin ${packageName}`);
|
|
845
902
|
const hook = instance.hooks[hookName];
|
|
846
903
|
if (hook) {
|
|
847
904
|
hook(...args);
|
|
@@ -1043,6 +1100,12 @@ export class PluginManager {
|
|
|
1043
1100
|
setGetBranchStateCallback(callback) {
|
|
1044
1101
|
this.getBranchStateCallback = callback;
|
|
1045
1102
|
}
|
|
1103
|
+
setEmotionEffectUpdaterCallback(callback) {
|
|
1104
|
+
this.emotionEffectUpdaterCallback = callback;
|
|
1105
|
+
}
|
|
1106
|
+
setDataContextGetter(callback) {
|
|
1107
|
+
this.dataContextGetter = callback;
|
|
1108
|
+
}
|
|
1046
1109
|
/**
|
|
1047
1110
|
* 全てのアセットプリロードが完了するまで待機
|
|
1048
1111
|
* @returns プリロード完了時にresolveするPromise
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* プラグインAPIからReactインスタンスを設定
|
|
3
|
+
*/
|
|
4
|
+
export declare function setReactRuntime(react: any): void;
|
|
5
|
+
/**
|
|
6
|
+
* JSX Transform用のjsx関数
|
|
7
|
+
*/
|
|
8
|
+
export declare function jsx(type: any, props: any, key?: any): any;
|
|
9
|
+
/**
|
|
10
|
+
* JSX Transform用のjsxs関数(複数子要素用)
|
|
11
|
+
*/
|
|
12
|
+
export declare function jsxs(type: any, props: any, key?: any): any;
|
|
13
|
+
/**
|
|
14
|
+
* Fragment用
|
|
15
|
+
*/
|
|
16
|
+
export declare function Fragment(props: {
|
|
17
|
+
children?: any;
|
|
18
|
+
}): any;
|
|
19
|
+
/**
|
|
20
|
+
* Reactフックと関数のプロキシ
|
|
21
|
+
*/
|
|
22
|
+
export declare const useState: (...args: any[]) => any;
|
|
23
|
+
export declare const useEffect: (...args: any[]) => any;
|
|
24
|
+
export declare const useCallback: (...args: any[]) => any;
|
|
25
|
+
export declare const useMemo: (...args: any[]) => any;
|
|
26
|
+
export declare const useRef: (...args: any[]) => any;
|
|
27
|
+
export declare const useContext: (...args: any[]) => any;
|
|
28
|
+
export declare const useReducer: (...args: any[]) => any;
|
|
29
|
+
export declare const createElement: (...args: any[]) => any;
|
|
30
|
+
declare const _default: {
|
|
31
|
+
createElement: (...args: any[]) => any;
|
|
32
|
+
Fragment: typeof Fragment;
|
|
33
|
+
useState: (...args: any[]) => any;
|
|
34
|
+
useEffect: (...args: any[]) => any;
|
|
35
|
+
useCallback: (...args: any[]) => any;
|
|
36
|
+
useMemo: (...args: any[]) => any;
|
|
37
|
+
useRef: (...args: any[]) => any;
|
|
38
|
+
useContext: (...args: any[]) => any;
|
|
39
|
+
useReducer: (...args: any[]) => any;
|
|
40
|
+
};
|
|
41
|
+
export default _default;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable import/no-anonymous-default-export */
|
|
3
|
+
let runtimeReact = null;
|
|
4
|
+
/**
|
|
5
|
+
* プラグインAPIからReactインスタンスを設定
|
|
6
|
+
*/
|
|
7
|
+
export function setReactRuntime(react) {
|
|
8
|
+
runtimeReact = react;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* JSX Transform用のjsx関数
|
|
12
|
+
*/
|
|
13
|
+
export function jsx(type, props, key) {
|
|
14
|
+
if (!runtimeReact) {
|
|
15
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
16
|
+
}
|
|
17
|
+
return runtimeReact.createElement(type, key ? Object.assign(Object.assign({}, props), { key }) : props);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* JSX Transform用のjsxs関数(複数子要素用)
|
|
21
|
+
*/
|
|
22
|
+
export function jsxs(type, props, key) {
|
|
23
|
+
if (!runtimeReact) {
|
|
24
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
25
|
+
}
|
|
26
|
+
return runtimeReact.createElement(type, key ? Object.assign(Object.assign({}, props), { key }) : props);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fragment用
|
|
30
|
+
*/
|
|
31
|
+
export function Fragment(props) {
|
|
32
|
+
if (!runtimeReact) {
|
|
33
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
34
|
+
}
|
|
35
|
+
return runtimeReact.createElement(runtimeReact.Fragment, null, props.children);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reactフックと関数のプロキシ
|
|
39
|
+
*/
|
|
40
|
+
export const useState = (...args) => {
|
|
41
|
+
if (!runtimeReact) {
|
|
42
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
43
|
+
}
|
|
44
|
+
return runtimeReact.useState(...args);
|
|
45
|
+
};
|
|
46
|
+
export const useEffect = (...args) => {
|
|
47
|
+
if (!runtimeReact) {
|
|
48
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
49
|
+
}
|
|
50
|
+
return runtimeReact.useEffect(...args);
|
|
51
|
+
};
|
|
52
|
+
export const useCallback = (...args) => {
|
|
53
|
+
if (!runtimeReact) {
|
|
54
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
55
|
+
}
|
|
56
|
+
return runtimeReact.useCallback(...args);
|
|
57
|
+
};
|
|
58
|
+
export const useMemo = (...args) => {
|
|
59
|
+
if (!runtimeReact) {
|
|
60
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
61
|
+
}
|
|
62
|
+
return runtimeReact.useMemo(...args);
|
|
63
|
+
};
|
|
64
|
+
export const useRef = (...args) => {
|
|
65
|
+
if (!runtimeReact) {
|
|
66
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
67
|
+
}
|
|
68
|
+
return runtimeReact.useRef(...args);
|
|
69
|
+
};
|
|
70
|
+
export const useContext = (...args) => {
|
|
71
|
+
if (!runtimeReact) {
|
|
72
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
73
|
+
}
|
|
74
|
+
return runtimeReact.useContext(...args);
|
|
75
|
+
};
|
|
76
|
+
export const useReducer = (...args) => {
|
|
77
|
+
if (!runtimeReact) {
|
|
78
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
79
|
+
}
|
|
80
|
+
return runtimeReact.useReducer(...args);
|
|
81
|
+
};
|
|
82
|
+
export const createElement = (...args) => {
|
|
83
|
+
if (!runtimeReact) {
|
|
84
|
+
throw new Error("React runtime not initialized. Make sure plugin is loaded properly.");
|
|
85
|
+
}
|
|
86
|
+
return runtimeReact.createElement(...args);
|
|
87
|
+
};
|
|
88
|
+
// デフォルトエクスポート(互換性用)
|
|
89
|
+
export default {
|
|
90
|
+
createElement,
|
|
91
|
+
Fragment,
|
|
92
|
+
useState,
|
|
93
|
+
useEffect,
|
|
94
|
+
useCallback,
|
|
95
|
+
useMemo,
|
|
96
|
+
useRef,
|
|
97
|
+
useContext,
|
|
98
|
+
useReducer,
|
|
99
|
+
};
|