@luna-editor/engine 0.3.0 → 0.3.2
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 +132 -58
- 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,73 @@ 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
|
-
|
|
109
|
-
|
|
117
|
+
// 開発環境ではキャッシュをバイパスして常に最新コードをロード
|
|
118
|
+
const isDevelopment = this.isDevelopment();
|
|
119
|
+
if (isDevelopment) {
|
|
120
|
+
// 開発環境では強制リロード(キャッシュをクリア)
|
|
121
|
+
globalLoadedPlugins.delete(packageName);
|
|
122
|
+
this.plugins.delete(packageName);
|
|
123
|
+
// ロード中の場合はそのPromiseを待って完了させる(二重ロード防止)
|
|
124
|
+
const existingLoadPromise = globalLoadingPlugins.get(packageName);
|
|
125
|
+
if (existingLoadPromise) {
|
|
126
|
+
yield existingLoadPromise;
|
|
127
|
+
const loaded = globalLoadedPlugins.get(packageName);
|
|
128
|
+
if (loaded) {
|
|
129
|
+
this.plugins.set(packageName, Object.assign(Object.assign({}, loaded), { config: config !== null && config !== void 0 ? config : loaded.config }));
|
|
130
|
+
for (const [type, component] of loaded.instance.components) {
|
|
131
|
+
this.componentRegistry.set(type, component);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
110
135
|
}
|
|
111
|
-
return;
|
|
112
136
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
// グローバルでロード中の場合はそのPromiseを待つ
|
|
122
|
-
const existingLoadPromise = globalLoadingPlugins.get(packageName);
|
|
123
|
-
if (existingLoadPromise) {
|
|
124
|
-
console.log(`Plugin ${packageName} is currently loading, waiting...`);
|
|
125
|
-
yield existingLoadPromise;
|
|
126
|
-
// ロード完了後にグローバルからコピー(新しいconfigで更新)
|
|
127
|
-
const loaded = globalLoadedPlugins.get(packageName);
|
|
128
|
-
if (loaded) {
|
|
129
|
-
const updatedPlugin = Object.assign(Object.assign({}, loaded), { config: config !== null && config !== void 0 ? config : loaded.config });
|
|
137
|
+
else {
|
|
138
|
+
// 本番環境のみキャッシュを使用
|
|
139
|
+
// グローバルに既にロード済みの場合はローカルにコピーしてスキップ
|
|
140
|
+
const globalLoaded = globalLoadedPlugins.get(packageName);
|
|
141
|
+
if (globalLoaded) {
|
|
142
|
+
// 新しいconfigで更新したコピーを作成
|
|
143
|
+
const updatedPlugin = Object.assign(Object.assign({}, globalLoaded), { config: config !== null && config !== void 0 ? config : globalLoaded.config });
|
|
130
144
|
this.plugins.set(packageName, updatedPlugin);
|
|
131
|
-
|
|
145
|
+
// コンポーネントレジストリにも登録
|
|
146
|
+
for (const [type, component] of globalLoaded.instance.components) {
|
|
132
147
|
this.componentRegistry.set(type, component);
|
|
133
148
|
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (!isDevelopment) {
|
|
153
|
+
// 本番環境のみ:ローカルに既にロード済みの場合はconfigだけ更新してスキップ
|
|
154
|
+
const localLoaded = this.plugins.get(packageName);
|
|
155
|
+
if (localLoaded) {
|
|
156
|
+
// configを更新
|
|
157
|
+
localLoaded.config = config !== null && config !== void 0 ? config : localLoaded.config;
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// 本番環境のみ:グローバルでロード中の場合はそのPromiseを待つ
|
|
161
|
+
const existingLoadPromise = globalLoadingPlugins.get(packageName);
|
|
162
|
+
if (existingLoadPromise) {
|
|
163
|
+
yield existingLoadPromise;
|
|
164
|
+
// ロード完了後にグローバルからコピー(新しいconfigで更新)
|
|
165
|
+
const loaded = globalLoadedPlugins.get(packageName);
|
|
166
|
+
if (loaded) {
|
|
167
|
+
const updatedPlugin = Object.assign(Object.assign({}, loaded), { config: config !== null && config !== void 0 ? config : loaded.config });
|
|
168
|
+
this.plugins.set(packageName, updatedPlugin);
|
|
169
|
+
for (const [type, component] of loaded.instance.components) {
|
|
170
|
+
this.componentRegistry.set(type, component);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
134
174
|
}
|
|
135
|
-
return;
|
|
136
175
|
}
|
|
137
176
|
// ロード処理をPromiseとして保存
|
|
138
|
-
const loadPromise = this.doLoadPlugin(packageName, bundleUrl, config);
|
|
177
|
+
const loadPromise = this.doLoadPlugin(packageName, bundleUrl, config, assets);
|
|
139
178
|
globalLoadingPlugins.set(packageName, loadPromise);
|
|
140
179
|
try {
|
|
141
180
|
yield loadPromise;
|
|
@@ -146,7 +185,7 @@ export class PluginManager {
|
|
|
146
185
|
}
|
|
147
186
|
});
|
|
148
187
|
}
|
|
149
|
-
doLoadPlugin(packageName, bundleUrl, config) {
|
|
188
|
+
doLoadPlugin(packageName, bundleUrl, config, assets) {
|
|
150
189
|
return __awaiter(this, void 0, void 0, function* () {
|
|
151
190
|
try {
|
|
152
191
|
// スクリプトタグで動的にプラグインを読み込む
|
|
@@ -160,11 +199,16 @@ export class PluginManager {
|
|
|
160
199
|
components: new Map(),
|
|
161
200
|
assetUrls: new Map(),
|
|
162
201
|
};
|
|
202
|
+
// 外部アプリから渡されたアセットURLを事前にキャッシュ
|
|
203
|
+
if (assets) {
|
|
204
|
+
for (const asset of assets) {
|
|
205
|
+
instance.assetUrls.set(asset.filename, asset.url);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
163
208
|
// プラグインAPIを作成
|
|
164
209
|
const api = this.createPluginAPI(packageName, instance);
|
|
165
210
|
// プラグインをセットアップ
|
|
166
211
|
plugin.setup(api);
|
|
167
|
-
console.log(`Plugin ${packageName} setup completed. Hooks:`, Object.keys(instance.hooks));
|
|
168
212
|
const loadedPlugin = {
|
|
169
213
|
plugin,
|
|
170
214
|
instance,
|
|
@@ -203,9 +247,7 @@ export class PluginManager {
|
|
|
203
247
|
};
|
|
204
248
|
// プラグインバンドルをfetchで取得して実行
|
|
205
249
|
// 開発環境ではキャッシュを無効化してホットリロードを確実に動作させる
|
|
206
|
-
const isDevelopment =
|
|
207
|
-
window.location.hostname === "127.0.0.1" ||
|
|
208
|
-
window.location.port === "3000";
|
|
250
|
+
const isDevelopment = this.isDevelopment();
|
|
209
251
|
const fetchOptions = isDevelopment
|
|
210
252
|
? {
|
|
211
253
|
cache: "no-cache",
|
|
@@ -215,7 +257,6 @@ export class PluginManager {
|
|
|
215
257
|
},
|
|
216
258
|
}
|
|
217
259
|
: {};
|
|
218
|
-
console.log(`🔄 Loading plugin ${packageName} (dev: ${isDevelopment}, cache: ${isDevelopment ? "disabled" : "enabled"})`);
|
|
219
260
|
fetch(url, fetchOptions)
|
|
220
261
|
.then((response) => {
|
|
221
262
|
if (!response.ok) {
|
|
@@ -589,16 +630,26 @@ export class PluginManager {
|
|
|
589
630
|
preload: (filenames) => {
|
|
590
631
|
const preloadPromise = (() => __awaiter(this, void 0, void 0, function* () {
|
|
591
632
|
const promises = filenames.map((filename) => __awaiter(this, void 0, void 0, function* () {
|
|
592
|
-
// API
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
633
|
+
// 既にキャッシュされたURLがあればAPIフェッチをスキップ
|
|
634
|
+
let finalUrl = instance.assetUrls.get(filename);
|
|
635
|
+
if (!finalUrl) {
|
|
636
|
+
// APIエンドポイントURL
|
|
637
|
+
const encodedPackageName = encodeURIComponent(packageName);
|
|
638
|
+
const encodedFilename = encodeURIComponent(filename);
|
|
639
|
+
const apiUrl = `/api/plugin/${encodedPackageName}/assets/${encodedFilename}`;
|
|
640
|
+
// fetchでリダイレクト後の最終URLを取得
|
|
641
|
+
try {
|
|
642
|
+
const response = yield fetch(apiUrl, { method: "HEAD" });
|
|
643
|
+
finalUrl = response.url; // リダイレクト後の最終URL
|
|
644
|
+
// 最終URLをキャッシュに保存
|
|
645
|
+
instance.assetUrls.set(filename, finalUrl);
|
|
646
|
+
}
|
|
647
|
+
catch (error) {
|
|
648
|
+
console.error(`Failed to preload asset: ${filename}`, error);
|
|
649
|
+
return Promise.resolve();
|
|
650
|
+
}
|
|
651
|
+
}
|
|
597
652
|
try {
|
|
598
|
-
const response = yield fetch(apiUrl, { method: "HEAD" });
|
|
599
|
-
const finalUrl = response.url; // リダイレクト後の最終URL
|
|
600
|
-
// 最終URLをキャッシュに保存
|
|
601
|
-
instance.assetUrls.set(filename, finalUrl);
|
|
602
653
|
// 画像をプリロード
|
|
603
654
|
if (filename.match(/\.(png|jpg|jpeg|gif|webp)$/i)) {
|
|
604
655
|
return new Promise((resolve, reject) => {
|
|
@@ -621,7 +672,6 @@ export class PluginManager {
|
|
|
621
672
|
catch (error) {
|
|
622
673
|
console.error(`Failed to preload asset: ${filename}`, error);
|
|
623
674
|
}
|
|
624
|
-
return Promise.resolve();
|
|
625
675
|
}));
|
|
626
676
|
yield Promise.all(promises);
|
|
627
677
|
}))();
|
|
@@ -679,7 +729,6 @@ export class PluginManager {
|
|
|
679
729
|
}
|
|
680
730
|
instance.components.set(type, component);
|
|
681
731
|
this.componentRegistry.set(type, component);
|
|
682
|
-
console.log(`Plugin ${packageName} registered component: ${type}`);
|
|
683
732
|
},
|
|
684
733
|
};
|
|
685
734
|
const uiAPI = {
|
|
@@ -777,8 +826,14 @@ export class PluginManager {
|
|
|
777
826
|
},
|
|
778
827
|
},
|
|
779
828
|
data: {
|
|
780
|
-
get: () => {
|
|
781
|
-
|
|
829
|
+
get: (key) => {
|
|
830
|
+
if (this.dataContextGetter) {
|
|
831
|
+
const context = this.dataContextGetter();
|
|
832
|
+
const value = context === null || context === void 0 ? void 0 : context[key];
|
|
833
|
+
return value;
|
|
834
|
+
}
|
|
835
|
+
console.warn("DataContext getter is not registered. Make sure to call setDataContextGetter.");
|
|
836
|
+
return undefined;
|
|
782
837
|
},
|
|
783
838
|
subscribe: () => {
|
|
784
839
|
throw new Error("DataAPI.subscribe() can only be called from within DataProvider context");
|
|
@@ -804,13 +859,26 @@ export class PluginManager {
|
|
|
804
859
|
setVolumes: () => {
|
|
805
860
|
throw new Error("DataAPI.setVolumes() can only be called from within DataProvider context");
|
|
806
861
|
},
|
|
862
|
+
updateEmotionEffect: (state) => {
|
|
863
|
+
if (this.emotionEffectUpdaterCallback) {
|
|
864
|
+
this.emotionEffectUpdaterCallback(state);
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
console.warn("updateEmotionEffect callback is not registered. Make sure to call setEmotionEffectUpdaterCallback.");
|
|
868
|
+
}
|
|
869
|
+
},
|
|
807
870
|
},
|
|
808
871
|
};
|
|
809
872
|
}
|
|
810
873
|
applyStyles(elementName, classNames) {
|
|
811
874
|
const element = this.styleElements.get(elementName);
|
|
812
875
|
if (element) {
|
|
813
|
-
|
|
876
|
+
// 元のクラス名を取得し、プラグインから追加されたクラスと結合
|
|
877
|
+
const originalClassName = this.originalClassNames.get(elementName) || "";
|
|
878
|
+
const pluginClassNames = classNames.join(" ");
|
|
879
|
+
element.className = originalClassName
|
|
880
|
+
? `${originalClassName} ${pluginClassNames}`
|
|
881
|
+
: pluginClassNames;
|
|
814
882
|
}
|
|
815
883
|
}
|
|
816
884
|
hideEffect(effectId, instance) {
|
|
@@ -831,17 +899,17 @@ export class PluginManager {
|
|
|
831
899
|
// DOM要素にdata-style-element-name属性を追加
|
|
832
900
|
element.setAttribute("data-style-element-name", name);
|
|
833
901
|
this.styleElements.set(name, element);
|
|
902
|
+
// 元のクラス名を保存(初回登録時のみ)
|
|
903
|
+
if (!this.originalClassNames.has(name)) {
|
|
904
|
+
this.originalClassNames.set(name, element.className);
|
|
905
|
+
}
|
|
834
906
|
}
|
|
835
907
|
// フック呼び出しメソッド
|
|
836
908
|
callHook(hookName, ...args) {
|
|
837
|
-
console.log(`Calling hook: ${hookName}`, args);
|
|
838
|
-
console.log(`Number of plugins: ${this.plugins.size}`);
|
|
839
909
|
this.plugins.forEach((loadedPlugin, packageName) => {
|
|
840
910
|
const { instance, enabled } = loadedPlugin;
|
|
841
|
-
console.log(`Plugin ${packageName}: enabled=${enabled}, has hook=${!!instance.hooks[hookName]}`);
|
|
842
911
|
if (enabled && instance.hooks[hookName]) {
|
|
843
912
|
try {
|
|
844
|
-
console.log(`Executing hook ${hookName} for plugin ${packageName}`);
|
|
845
913
|
const hook = instance.hooks[hookName];
|
|
846
914
|
if (hook) {
|
|
847
915
|
hook(...args);
|
|
@@ -1043,6 +1111,12 @@ export class PluginManager {
|
|
|
1043
1111
|
setGetBranchStateCallback(callback) {
|
|
1044
1112
|
this.getBranchStateCallback = callback;
|
|
1045
1113
|
}
|
|
1114
|
+
setEmotionEffectUpdaterCallback(callback) {
|
|
1115
|
+
this.emotionEffectUpdaterCallback = callback;
|
|
1116
|
+
}
|
|
1117
|
+
setDataContextGetter(callback) {
|
|
1118
|
+
this.dataContextGetter = callback;
|
|
1119
|
+
}
|
|
1046
1120
|
/**
|
|
1047
1121
|
* 全てのアセットプリロードが完了するまで待機
|
|
1048
1122
|
* @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
|
+
};
|