| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- import { readFileSync } from 'node:fs'
- import { registerHooks } from 'node:module'
- import { parse, compileScript, compileTemplate } from '@vue/compiler-sfc'
- const SRC = '../../../../../src/modules/cockpit/'
- const ENV_STUB = 'const import_meta_env = { BASE_URL: "/", MODE: "development", DEV: true, PROD: false, SSR: false };'
- registerHooks({
- load(url, context, nextLoad) {
- if (url.endsWith('.json')) return { format: 'module', shortCircuit: true, source: 'export default ' + readFileSync(new URL(url), 'utf8') }
- if (url.endsWith('.css')) return { format: 'module', shortCircuit: true, source: 'export default {}' }
- if (url.endsWith('.js') && url.includes('/src/')) {
- const raw = readFileSync(new URL(url), 'utf8')
- if (raw.includes('import.meta.env')) return { format: 'module', shortCircuit: true, source: ENV_STUB + raw.replace(/import\.meta\.env/g, 'import_meta_env') }
- }
- if (url.endsWith('.vue')) {
- const source = readFileSync(new URL(url), 'utf8')
- const { descriptor } = parse(source, { filename: url })
- const script = compileScript(descriptor, { id: 'replay', genDefaultAs: '__sfc__' })
- const template = compileTemplate({ source: descriptor.template.content, filename: url, id: 'replay', ssr: true, compilerOptions: { bindingMetadata: script.bindings } })
- const body = script.content.replace(/import\.meta\.env/g, 'import_meta_env')
- return { format: 'module', shortCircuit: true, source: ENV_STUB + '\n' + body + '\n' + template.code + '\n__sfc__.ssrRender = ssrRender; export default __sfc__;' }
- }
- return nextLoad(url, context)
- },
- })
- // 最小 DOM/window stub(启动计划里只有 WS/字体/计时器需要它们)
- const noop = () => {}
- globalThis.window = globalThis.window || {
- addEventListener: noop, removeEventListener: noop, setTimeout, clearTimeout, setInterval, clearInterval,
- requestAnimationFrame: (cb) => setTimeout(() => cb(Date.now()), 16), cancelAnimationFrame: noop,
- devicePixelRatio: 1, innerWidth: 1680, innerHeight: 950,
- location: { href: 'http://127.0.0.1:8000/#/cockpit', search: '', hash: '#/cockpit', origin: 'http://127.0.0.1:8000' },
- matchMedia: () => ({ matches: false, addEventListener: noop, removeEventListener: noop }),
- getComputedStyle: () => ({ getPropertyValue: () => '' }),
- ResizeObserver: class { observe() {} unobserve() {} disconnect() {} },
- }
- globalThis.document = globalThis.document || {
- activeElement: null, visibilityState: 'visible', hidden: false,
- createElement: () => ({ style: {}, setAttribute: noop, appendChild: noop, addEventListener: noop, classList: { add: noop, remove: noop } }),
- createElementNS: () => ({ style: {}, setAttribute: noop, appendChild: noop, addEventListener: noop }),
- createTextNode: () => ({}), createComment: () => ({}),
- querySelector: () => null, querySelectorAll: () => [], getElementById: () => null,
- head: { appendChild: noop, children: [] }, body: { appendChild: noop, children: [] },
- addEventListener: noop, removeEventListener: noop,
- }
- if (!globalThis.navigator) Object.defineProperty(globalThis, 'navigator', { value: { userAgent: 'node' }, configurable: true })
- for (const k of ['ResizeObserver', 'matchMedia', 'getComputedStyle']) if (globalThis[k] === undefined) globalThis[k] = globalThis.window[k]
- const { createPinia, setActivePinia } = await import('pinia')
- setActivePinia(createPinia())
- const { loadCockpitConfig } = await import(SRC + 'services/cockpitConfig.js')
- const { planCockpitStartup } = await import(SRC + 'domain/startupPlan.js')
- const { STARTUP_ACTION } = await import(SRC + 'domain/startupPlan.js')
- const { registerMockTransport, resetMockTransportsForTest } = await import(SRC + 'services/cockpitApi.js')
- const { registerCockpitMocks } = await import(SRC + 'mocks/contractMocks.js')
- const { useMapStore } = await import(SRC + 'stores/mapStore.js')
- const { useDetailStore } = await import(SRC + 'stores/detailStore.js')
- const { usePipeNetworkStore } = await import(SRC + 'stores/pipeNetworkStore.js')
- const { useInfrastructureStore } = await import(SRC + 'stores/infrastructureStore.js')
- const { useMonitoringStore } = await import(SRC + 'stores/monitoringStore.js')
- const { useEventStore } = await import(SRC + 'stores/eventStore.js')
- const { useOverviewStore } = await import(SRC + 'stores/overviewStore.js')
- const { useRuntimeStore } = await import(SRC + 'stores/runtimeStore.js')
- const { useFilterStore } = await import(SRC + 'stores/filterStore.js')
- const requests = []
- resetMockTransportsForTest()
- registerCockpitMocks({
- scenario: 'success',
- handlers: {
- registerMockTransport: (path, handler) => registerMockTransport(path, (req) => { requests.push(typeof req === 'string' ? req : JSON.stringify(req).slice(0, 120)); return handler(req) }),
- resetMockTransportsForTest,
- },
- })
- const result = await loadCockpitConfig()
- const plan = planCockpitStartup(result.config)
- console.log('config state =', result.state, 'dataSource =', result.config.dataSource)
- console.log('plan.actions =', plan.actions.join(', '))
- const filterStore = useFilterStore()
- const mapStore = useMapStore()
- const detailStore = useDetailStore()
- const pipeNetworkStore = usePipeNetworkStore()
- const infrastructureStore = useInfrastructureStore()
- const monitoringStore = useMonitoringStore()
- const eventStore = useEventStore()
- const overviewStore = useOverviewStore()
- const runtimeStore = useRuntimeStore()
- const scope = { value: filterStore.scope }
- let failedAt = null
- for (const action of plan.actions) {
- try {
- if (action === STARTUP_ACTION.REGISTER_MOCKS) continue
- if (action === STARTUP_ACTION.LOAD_MAP_SUMMARY) { mapStore.setup({ config: result.config, industry: 'all', scope: 'all', deviceType: '', pointStatus: [] }); continue }
- if (action === STARTUP_ACTION.LOAD_SHARED_SECTIONS) { detailStore.loadSharedSections({ config: result.config }); pipeNetworkStore.load({ industry: 'all', scope: 'all', config: result.config }); continue }
- if (action === STARTUP_ACTION.LOAD_INFRASTRUCTURE_PANELS) { infrastructureStore.configure({ config: result.config }); infrastructureStore.loadPanels({ industry: 'all', scope: 'all' }); continue }
- if (action === STARTUP_ACTION.LOAD_MONITORING_PANELS) { monitoringStore.configure({ config: result.config }); monitoringStore.loadPanels({ industry: 'all', deviceType: '', pointStatus: [], scope: 'all' }); continue }
- if (action === STARTUP_ACTION.LOAD_EVENT_PANELS) { eventStore.configure({ config: result.config }); eventStore.loadPanels({ mode: 'WARNING', range: '7d', industry: 'all' }); continue }
- if (action === STARTUP_ACTION.LOAD_OVERVIEW_PANELS) { overviewStore.configure({ config: result.config }); overviewStore.loadPanels(); continue }
- if (action === STARTUP_ACTION.START_WEBSOCKET) { runtimeStore.startWithConfig(result.config, { scenario: 'success' }); continue }
- if (action === STARTUP_ACTION.START_FRESHNESS) { continue }
- } catch (error) {
- failedAt = action + ' → ' + (error && error.stack ? error.stack.split('\n').slice(0, 4).join(' | ') : error)
- break
- }
- }
- console.log('启动计划同步执行:', failedAt || '全部动作未抛错')
- await new Promise((r) => setTimeout(r, 300))
- console.log('请求数 =', requests.length)
- console.log('mapStore.filters =', JSON.stringify(mapStore.filters))
- console.log('mapStore.summary.phase =', mapStore.summary.phase)
- console.log('infrastructure 分区 loaded =', Object.entries(infrastructureStore.sections).map(([k, v]) => k + ':' + v.state + '/' + v.loaded).join(' '))
- process.exit(0)
|