@kennofizet/apphub-frontend 0.1.7 → 0.1.8
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/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { getCurrentInstance } from 'vue'
|
|
2
|
-
import { getAppHubStore } from '../moduleStore.js'
|
|
1
|
+
import { getCurrentInstance, inject } from 'vue'
|
|
2
|
+
import { APPHUB_MODULE_STORE_KEY, getAppHubStore } from '../moduleStore.js'
|
|
3
3
|
|
|
4
4
|
export function resolveRootApp(instance = getCurrentInstance()) {
|
|
5
5
|
if (!instance) return null
|
|
6
6
|
return instance.appContext?.app ?? instance.app ?? null
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/** Resolve module store — inject first (always same instance), then WeakMap by Vue app. */
|
|
10
|
+
export function useAppHubModuleStore() {
|
|
11
|
+
const fromInject = inject(APPHUB_MODULE_STORE_KEY, null)
|
|
12
|
+
if (fromInject) return fromInject
|
|
13
|
+
return getAppHubStore(resolveRootApp())
|
|
14
|
+
}
|
|
15
|
+
|
|
9
16
|
export function getHostApiForApp(app) {
|
|
10
17
|
return getAppHubStore(app)?.facade ?? null
|
|
11
18
|
}
|
|
@@ -20,5 +27,9 @@ export function isBackendReadyForApp(app) {
|
|
|
20
27
|
* so publisher app code cannot access grantBridgeScope or internal docs.
|
|
21
28
|
*/
|
|
22
29
|
export function useAppHubHostApi() {
|
|
23
|
-
return
|
|
30
|
+
return useAppHubModuleStore()?.facade ?? null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function isBackendReadyFromStore(store) {
|
|
34
|
+
return !!(store?.credentials?.backendUrl && store?.credentials?.token)
|
|
24
35
|
}
|
package/src/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { APPHUB_ZONE_CONTEXT_KEY } from './composables/useAppHubZoneContext.js'
|
|
|
8
8
|
import { createAppStoreState, provideAppStore } from './modules/app-store/index.js'
|
|
9
9
|
import { AppHubDesktop } from './modules/desktop/index.js'
|
|
10
10
|
import { AppHubRunner } from './modules/runner/index.js'
|
|
11
|
-
import { getAppHubStore, registerAppHubStore } from './moduleStore.js'
|
|
11
|
+
import { getAppHubStore, registerAppHubStore, APPHUB_MODULE_STORE_KEY } from './moduleStore.js'
|
|
12
12
|
import {
|
|
13
13
|
createWindowManagerState,
|
|
14
14
|
provideWindowManager,
|
|
@@ -417,6 +417,7 @@ export function installAppHubModule(vueApp, options = {}) {
|
|
|
417
417
|
|
|
418
418
|
if (store) {
|
|
419
419
|
vueApp.provide('apphubHostApp', vueApp)
|
|
420
|
+
vueApp.provide(APPHUB_MODULE_STORE_KEY, store)
|
|
420
421
|
apphubDebug('install', 'installAppHubModule re-install', {
|
|
421
422
|
appUid: vueApp._uid ?? null,
|
|
422
423
|
hasToken: !!(options.token),
|
|
@@ -454,6 +455,7 @@ export function installAppHubModule(vueApp, options = {}) {
|
|
|
454
455
|
|
|
455
456
|
vueApp.provide('apphubOptions', moduleOptions)
|
|
456
457
|
vueApp.provide('apphubHostApp', vueApp)
|
|
458
|
+
vueApp.provide(APPHUB_MODULE_STORE_KEY, store)
|
|
457
459
|
vueApp.component('AppHubDesktop', AppHubDesktop)
|
|
458
460
|
vueApp.component('AppHubRunner', AppHubRunner)
|
|
459
461
|
|
|
@@ -468,7 +470,7 @@ export function isAppHubModuleInstalled(vueApp) {
|
|
|
468
470
|
return vueApp != null && getAppHubStore(vueApp) != null
|
|
469
471
|
}
|
|
470
472
|
|
|
471
|
-
export { useAppHubHostApi } from './composables/useAppHubHostApi.js'
|
|
473
|
+
export { useAppHubHostApi, useAppHubModuleStore } from './composables/useAppHubHostApi.js'
|
|
472
474
|
export { useAppHubZoneContext } from './composables/useAppHubZoneContext.js'
|
|
473
475
|
export { createAppHubApi } from './api/index.js'
|
|
474
476
|
export { createCoreApi } from './api/coreApi.js'
|
package/src/moduleStore.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
/**
|
|
2
|
-
const
|
|
1
|
+
/** Internal inject key — package components only; not part of public host API. */
|
|
2
|
+
export const APPHUB_MODULE_STORE_KEY = Symbol('apphubModuleStore')
|
|
3
|
+
|
|
4
|
+
const REGISTRY_KEY = '__kennofizet_apphub_installed_apps__'
|
|
5
|
+
|
|
6
|
+
/** Shared WeakMap — Vite may load this module twice (host bundle vs SFC chunks). */
|
|
7
|
+
function getInstalledAppsRegistry() {
|
|
8
|
+
const root = typeof globalThis !== 'undefined' ? globalThis : global
|
|
9
|
+
if (!root[REGISTRY_KEY]) {
|
|
10
|
+
root[REGISTRY_KEY] = new WeakMap()
|
|
11
|
+
}
|
|
12
|
+
return root[REGISTRY_KEY]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const installedApps = getInstalledAppsRegistry()
|
|
3
16
|
|
|
4
17
|
export function registerAppHubStore(app, store) {
|
|
5
18
|
installedApps.set(app, store)
|
|
@@ -97,11 +97,11 @@
|
|
|
97
97
|
</template>
|
|
98
98
|
|
|
99
99
|
<script setup>
|
|
100
|
-
import { computed,
|
|
100
|
+
import { computed, inject, onMounted, ref, watch } from 'vue'
|
|
101
101
|
import {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
isBackendReadyFromStore,
|
|
103
|
+
useAppHubHostApi,
|
|
104
|
+
useAppHubModuleStore,
|
|
105
105
|
} from '../../../composables/useAppHubHostApi.js'
|
|
106
106
|
import { useAppHubZoneContext } from '../../../composables/useAppHubZoneContext.js'
|
|
107
107
|
import { t } from '../../../i18n/index.js'
|
|
@@ -109,7 +109,7 @@ import { resolveLang } from '../../../i18n/resolveLang.js'
|
|
|
109
109
|
import { CATALOG_MODE_STORE } from '../constants/catalogModes.js'
|
|
110
110
|
import { useCatalogInfiniteScroll } from '../composables/useCatalogInfiniteScroll.js'
|
|
111
111
|
import { useAppStore } from '../composables/useAppStore.js'
|
|
112
|
-
import { apphubDebug,
|
|
112
|
+
import { apphubDebug, describeHostApi } from '../../../utils/apphubDebug.js'
|
|
113
113
|
import AppHubAppStoreCard from './AppHubAppStoreCard.vue'
|
|
114
114
|
import AppHubAppStoreSettingsPanel from './AppHubAppStoreSettingsPanel.vue'
|
|
115
115
|
|
|
@@ -123,8 +123,9 @@ const props = defineProps({
|
|
|
123
123
|
const settingsOpen = ref(false)
|
|
124
124
|
const appStore = useAppStore()
|
|
125
125
|
const catalog = appStore.catalogs.store
|
|
126
|
-
const
|
|
127
|
-
const
|
|
126
|
+
const hubStore = useAppHubModuleStore()
|
|
127
|
+
const hostApi = useAppHubHostApi()
|
|
128
|
+
const rootApp = inject('apphubHostApp', null)
|
|
128
129
|
const zone = useAppHubZoneContext()
|
|
129
130
|
const moduleOptions = inject('apphubOptions', {})
|
|
130
131
|
const lang = computed(() => resolveLang(moduleOptions?.language, 'vi'))
|
|
@@ -154,35 +155,29 @@ const labels = computed(() => ({
|
|
|
154
155
|
|
|
155
156
|
function hostApiOptions() {
|
|
156
157
|
return {
|
|
157
|
-
backendReady:
|
|
158
|
+
backendReady: isBackendReadyFromStore(hubStore),
|
|
158
159
|
mode: CATALOG_MODE_STORE,
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
async function reloadCatalog(source = 'manual') {
|
|
163
|
-
|
|
164
|
-
apphubDebug('app-store', 'reloadCatalog skipped — no rootApp', { source, rootAppSource })
|
|
165
|
-
return
|
|
166
|
-
}
|
|
167
|
-
const hostApi = getHostApiForApp(rootApp)
|
|
164
|
+
const api = hostApi
|
|
168
165
|
const opts = hostApiOptions()
|
|
169
166
|
apphubDebug('app-store', 'reloadCatalog', {
|
|
170
167
|
source,
|
|
171
|
-
|
|
172
|
-
...
|
|
173
|
-
...describeHostApi(hostApi),
|
|
168
|
+
storeFromInject: !!hubStore,
|
|
169
|
+
...describeHostApi(api),
|
|
174
170
|
backendReady: opts.backendReady,
|
|
175
171
|
originBootstrapLoading: moduleOptions?.originBootstrapLoading,
|
|
176
172
|
originBlocked: moduleOptions?.originBlocked,
|
|
177
173
|
catalogLoaded: catalog.loaded,
|
|
178
174
|
catalogError: catalog.error,
|
|
179
175
|
})
|
|
180
|
-
await appStore.loadCatalog(
|
|
176
|
+
await appStore.loadCatalog(api, opts)
|
|
181
177
|
}
|
|
182
178
|
|
|
183
179
|
async function loadMore() {
|
|
184
|
-
|
|
185
|
-
await appStore.loadMoreCatalog(getHostApiForApp(rootApp), CATALOG_MODE_STORE, hostApiOptions())
|
|
180
|
+
await appStore.loadMoreCatalog(hostApi, CATALOG_MODE_STORE, hostApiOptions())
|
|
186
181
|
}
|
|
187
182
|
|
|
188
183
|
const { rootRef: scrollRoot, sentinelRef: scrollSentinel } = useCatalogInfiniteScroll({
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
</template>
|
|
63
63
|
|
|
64
64
|
<script setup>
|
|
65
|
-
import { computed,
|
|
65
|
+
import { computed, inject, onMounted, reactive, ref, watch } from 'vue'
|
|
66
66
|
import {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
isBackendReadyFromStore,
|
|
68
|
+
useAppHubHostApi,
|
|
69
|
+
useAppHubModuleStore,
|
|
70
70
|
} from '../../../composables/useAppHubHostApi.js'
|
|
71
71
|
import { useAppHubZoneContext } from '../../../composables/useAppHubZoneContext.js'
|
|
72
72
|
import { t } from '../../../i18n/index.js'
|
|
@@ -83,7 +83,9 @@ const props = defineProps({
|
|
|
83
83
|
|
|
84
84
|
const appStore = useAppStore()
|
|
85
85
|
const catalog = appStore.catalogs.draft
|
|
86
|
-
const
|
|
86
|
+
const hubStore = useAppHubModuleStore()
|
|
87
|
+
const hostApi = useAppHubHostApi()
|
|
88
|
+
const rootApp = inject('apphubHostApp', null)
|
|
87
89
|
const zone = useAppHubZoneContext()
|
|
88
90
|
const moduleOptions = inject('apphubOptions', {})
|
|
89
91
|
const lang = computed(() => resolveLang(moduleOptions?.language, 'vi'))
|
|
@@ -119,19 +121,17 @@ const labels = computed(() => ({
|
|
|
119
121
|
|
|
120
122
|
function hostApiOptions() {
|
|
121
123
|
return {
|
|
122
|
-
backendReady:
|
|
124
|
+
backendReady: isBackendReadyFromStore(hubStore),
|
|
123
125
|
mode: CATALOG_MODE_DRAFT,
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
async function reloadCatalog() {
|
|
128
|
-
|
|
129
|
-
await appStore.loadCatalog(getHostApiForApp(rootApp), hostApiOptions())
|
|
130
|
+
await appStore.loadCatalog(hostApi, hostApiOptions())
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
async function loadMore() {
|
|
133
|
-
|
|
134
|
-
await appStore.loadMoreCatalog(getHostApiForApp(rootApp), CATALOG_MODE_DRAFT, hostApiOptions())
|
|
134
|
+
await appStore.loadMoreCatalog(hostApi, CATALOG_MODE_DRAFT, hostApiOptions())
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
const { rootRef: scrollRoot, sentinelRef: scrollSentinel } = useCatalogInfiniteScroll({
|
|
@@ -150,7 +150,7 @@ async function onUninstall(app) {
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
async function onPing(app) {
|
|
153
|
-
const api =
|
|
153
|
+
const api = hostApi
|
|
154
154
|
if (!api?.ping || !app?.slug) return
|
|
155
155
|
pingingSlug.value = app.slug
|
|
156
156
|
delete pingResults[app.slug]
|