@nexia/sdk 0.8.5 → 0.8.7
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/changelog/0.8.6/en.md +11 -0
- package/changelog/0.8.6/ko.md +11 -0
- package/dist/host.d.ts +6 -0
- package/dist/host.js +21 -19
- package/dist/vite.mjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: published
|
|
3
|
+
version: 0.8.6
|
|
4
|
+
date: 2026-10-14
|
|
5
|
+
title: Development App updates
|
|
6
|
+
description: Optional loader support for updating development Apps within the Shell.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
The optional `wrapLoader` host hook and `development_updates: 1` build metadata let compatible hosts replace development App surfaces without reloading the Shell. Existing hosts can omit the hook.
|
|
10
|
+
|
|
11
|
+
Use Core 0.8.34, CLI 0.2.0-alpha.13 and sandbox-manager 0.1.0-alpha.24 or compatible later versions, then rebuild the development App with React SDK 0.8.6. Unsaved forms and pending writes defer replacement. Component-local state may reset; this is not React Fast Refresh.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: published
|
|
3
|
+
version: 0.8.6
|
|
4
|
+
date: 2026-10-14
|
|
5
|
+
title: 개발 앱 변경 반영
|
|
6
|
+
description: Shell 안에서 개발 앱을 갱신하기 위한 선택적 로더 계약입니다.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
선택적 `wrapLoader` 호스트 훅과 `development_updates: 1` 빌드 메타데이터를 추가합니다. 이를 지원하는 호스트는 Shell을 새로고침하지 않고 개발 앱 화면을 교체할 수 있습니다. 기존 호스트는 훅을 생략할 수 있습니다.
|
|
10
|
+
|
|
11
|
+
Core 0.8.34, CLI 0.2.0-alpha.13, sandbox-manager 0.1.0-alpha.24 또는 호환되는 이후 버전을 함께 적용하고 React SDK 0.8.6으로 개발 앱을 다시 빌드하세요. 미저장 폼이나 처리 중인 쓰기가 있으면 교체를 보류합니다. 컴포넌트 내부 상태는 초기화될 수 있으며 React Fast Refresh 방식은 아닙니다.
|
package/dist/host.d.ts
CHANGED
|
@@ -325,6 +325,12 @@ export interface NexiaAppRequestServices {
|
|
|
325
325
|
api: AxiosInstance;
|
|
326
326
|
openFile: (href: string, options?: OpenFileOptions) => Promise<void>;
|
|
327
327
|
wrapComponent?: <P extends object>(component: ComponentType<P>) => ComponentType<P>;
|
|
328
|
+
/** Optional development host hook. Installed/Composer loaders remain unchanged. */
|
|
329
|
+
wrapLoader?: <P extends object>(key: string, load: () => Promise<{
|
|
330
|
+
default: ComponentType<P>;
|
|
331
|
+
}>) => () => Promise<{
|
|
332
|
+
default: ComponentType<P>;
|
|
333
|
+
}>;
|
|
328
334
|
}
|
|
329
335
|
/** Used by the SDK build facade, not by application source. Captures a fixed owner. */
|
|
330
336
|
export declare function bindNexiaAppRequestServices(appKey: string): {
|
package/dist/host.js
CHANGED
|
@@ -10,15 +10,18 @@ export function bindNexiaAppRequestServices(appKey) {
|
|
|
10
10
|
throw new Error('This host does not support App-bound frontend services.');
|
|
11
11
|
const services = resolve(appKey);
|
|
12
12
|
const wrap = (component) => services.wrapComponent?.(component) ?? component;
|
|
13
|
-
const loader = (load) =>
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
const loader = (key, load) => {
|
|
14
|
+
const wrapped = async () => {
|
|
15
|
+
const module = await load();
|
|
16
|
+
return { ...module, default: wrap(module.default) };
|
|
17
|
+
};
|
|
18
|
+
return services.wrapLoader?.(key, wrapped) ?? wrapped;
|
|
16
19
|
};
|
|
17
20
|
const inspectors = {
|
|
18
21
|
register(type, load) {
|
|
22
|
+
const wrapped = loader(`inspector:${type}`, load);
|
|
19
23
|
host().registries.resourceInspectorAdapterRegistry.register(type, async () => {
|
|
20
|
-
const
|
|
21
|
-
const Component = wrap(module.default);
|
|
24
|
+
const { default: Component } = await wrapped();
|
|
22
25
|
return { default: props => createElement(Component, props) };
|
|
23
26
|
});
|
|
24
27
|
},
|
|
@@ -26,8 +29,8 @@ export function bindNexiaAppRequestServices(appKey) {
|
|
|
26
29
|
const approvals = {
|
|
27
30
|
register(registration, legacyLoader) {
|
|
28
31
|
host().registries.approvalComposerBusinessFormRegistry.register(typeof registration === 'string'
|
|
29
|
-
? { formWidgetKey: registration, loader: loader(legacyLoader) }
|
|
30
|
-
: { ...registration, loader: loader(registration.loader) });
|
|
32
|
+
? { formWidgetKey: registration, loader: loader(`approval:${registration}`, legacyLoader) }
|
|
33
|
+
: { ...registration, loader: loader(`approval:${registration.formWidgetKey}`, registration.loader) });
|
|
31
34
|
},
|
|
32
35
|
};
|
|
33
36
|
return {
|
|
@@ -37,29 +40,32 @@ export function bindNexiaAppRequestServices(appKey) {
|
|
|
37
40
|
},
|
|
38
41
|
autoRegisterPackageSurfaces(options) {
|
|
39
42
|
host().runtime.autoRegisterPackageSurfaces({ ...options, appKey,
|
|
40
|
-
overview: options.overview && loader(options.overview),
|
|
41
|
-
surfaces: Object.fromEntries(Object.entries(options.surfaces).map(([key, load]) => [key, loader(load)])),
|
|
43
|
+
overview: options.overview && loader('overview', options.overview),
|
|
44
|
+
surfaces: Object.fromEntries(Object.entries(options.surfaces).map(([key, load]) => [key, loader(`surface:${key}`, load)])),
|
|
42
45
|
overrides: Object.fromEntries(Object.entries(options.overrides ?? {}).map(([key, value]) => [key,
|
|
43
|
-
typeof value === 'function' ? loader(value) : { ...value, load: loader(value.load) }])), });
|
|
46
|
+
typeof value === 'function' ? loader(`override:${key}`, value) : { ...value, load: loader(`override:${key}`, value.load) }])), });
|
|
44
47
|
},
|
|
45
48
|
approvalComposerBusinessFormRegistry: approvals,
|
|
46
49
|
processUserTaskFormRegistry: {
|
|
47
50
|
register(registration) {
|
|
48
|
-
host().registries.processUserTaskFormRegistry.register({ ...registration, loader: loader(registration.loader) });
|
|
51
|
+
host().registries.processUserTaskFormRegistry.register({ ...registration, loader: loader(`process:${registration.componentKey}`, registration.loader) });
|
|
49
52
|
},
|
|
50
53
|
},
|
|
51
54
|
dataMigrationRegistry: {
|
|
52
55
|
registerProvider: dataMigrationRegistry.registerProvider,
|
|
53
56
|
registerTarget: dataMigrationRegistry.registerTarget,
|
|
54
57
|
registerStage(registration) {
|
|
55
|
-
host().registries.dataMigrationRegistry.registerStage({ ...registration, ownerAppKey: appKey, loader: loader(registration.loader) });
|
|
58
|
+
host().registries.dataMigrationRegistry.registerStage({ ...registration, ownerAppKey: appKey, loader: loader(`migration:${registration.providerKey}:${registration.id}`, registration.loader) });
|
|
56
59
|
},
|
|
57
60
|
},
|
|
58
61
|
registerAgentComponent(name, component) {
|
|
59
|
-
|
|
62
|
+
if (services.wrapLoader)
|
|
63
|
+
host().runtime.registerLazyAgentComponent(name, loader(`agent:${name}`, async () => ({ default: component })));
|
|
64
|
+
else
|
|
65
|
+
host().runtime.registerAgentComponent(name, wrap(component));
|
|
60
66
|
},
|
|
61
67
|
registerLazyAgentComponent(name, load) {
|
|
62
|
-
host().runtime.registerLazyAgentComponent(name, loader(load));
|
|
68
|
+
host().runtime.registerLazyAgentComponent(name, loader(`agent:${name}`, load));
|
|
63
69
|
},
|
|
64
70
|
api: services.api,
|
|
65
71
|
openFile: services.openFile,
|
|
@@ -114,10 +120,6 @@ function waitForOperationPoll(signal) {
|
|
|
114
120
|
if (signal.aborted) {
|
|
115
121
|
return Promise.reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));
|
|
116
122
|
}
|
|
117
|
-
const delay = typeof document !== 'undefined'
|
|
118
|
-
&& document.visibilityState === 'hidden'
|
|
119
|
-
? 3000
|
|
120
|
-
: 1200;
|
|
121
123
|
return new Promise((resolve, reject) => {
|
|
122
124
|
const aborted = () => {
|
|
123
125
|
globalThis.clearTimeout(timer);
|
|
@@ -126,7 +128,7 @@ function waitForOperationPoll(signal) {
|
|
|
126
128
|
const timer = globalThis.setTimeout(() => {
|
|
127
129
|
signal.removeEventListener('abort', aborted);
|
|
128
130
|
resolve();
|
|
129
|
-
},
|
|
131
|
+
}, 5000);
|
|
130
132
|
signal.addEventListener('abort', aborted, { once: true });
|
|
131
133
|
});
|
|
132
134
|
}
|
package/dist/vite.mjs
CHANGED
|
@@ -60,7 +60,7 @@ export const { api, openFile, sendUserInvitation, useDataMigrationBackgroundOper
|
|
|
60
60
|
// Standalone App builds expose compatibility before executing their entry.
|
|
61
61
|
if (owners.length === 1) this.emitFile({
|
|
62
62
|
type: 'asset', fileName: 'nexia-host.json',
|
|
63
|
-
source: JSON.stringify({ version: 1, app_key: owners[0].appKey,
|
|
63
|
+
source: JSON.stringify({ version: 1, development_updates: 1, app_key: owners[0].appKey,
|
|
64
64
|
styles: Object.keys(bundle).filter(file => file.endsWith('.css')) }),
|
|
65
65
|
});
|
|
66
66
|
},
|