repluggable-core 0.0.0-pr349.66 → 0.0.0-pr351.71

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.
Files changed (37) hide show
  1. package/dist/es/src/repluggableAppDebug/index.d.ts +1 -1
  2. package/dist/es/src/repluggableAppDebug/index.d.ts.map +1 -1
  3. package/dist/es/src/repluggableAppDebug/index.js.map +1 -1
  4. package/dist/es/src/repluggableAppDebug/repluggableAppDebug.d.ts +20 -0
  5. package/dist/es/src/repluggableAppDebug/repluggableAppDebug.d.ts.map +1 -1
  6. package/dist/es/src/repluggableAppDebug/repluggableAppDebug.js +41 -42
  7. package/dist/es/src/repluggableAppDebug/repluggableAppDebug.js.map +1 -1
  8. package/dist/es/test/repluggableAppDebug.spec.js +122 -0
  9. package/dist/es/test/repluggableAppDebug.spec.js.map +1 -1
  10. package/dist/es/test/testKit.spec.js +44 -2
  11. package/dist/es/test/testKit.spec.js.map +1 -1
  12. package/dist/es/testKit/index.d.ts +10 -1
  13. package/dist/es/testKit/index.d.ts.map +1 -1
  14. package/dist/es/testKit/index.js +56 -13
  15. package/dist/es/testKit/index.js.map +1 -1
  16. package/dist/src/repluggableAppDebug/index.d.ts +1 -1
  17. package/dist/src/repluggableAppDebug/index.d.ts.map +1 -1
  18. package/dist/src/repluggableAppDebug/index.js.map +1 -1
  19. package/dist/src/repluggableAppDebug/repluggableAppDebug.d.ts +20 -0
  20. package/dist/src/repluggableAppDebug/repluggableAppDebug.d.ts.map +1 -1
  21. package/dist/src/repluggableAppDebug/repluggableAppDebug.js +41 -42
  22. package/dist/src/repluggableAppDebug/repluggableAppDebug.js.map +1 -1
  23. package/dist/test/repluggableAppDebug.spec.js +122 -0
  24. package/dist/test/repluggableAppDebug.spec.js.map +1 -1
  25. package/dist/test/testKit.spec.js +43 -1
  26. package/dist/test/testKit.spec.js.map +1 -1
  27. package/dist/testKit/index.d.ts +10 -1
  28. package/dist/testKit/index.d.ts.map +1 -1
  29. package/dist/testKit/index.js +58 -14
  30. package/dist/testKit/index.js.map +1 -1
  31. package/package.json +2 -2
  32. package/src/repluggableAppDebug/debug.d.ts +16 -1
  33. package/src/repluggableAppDebug/index.ts +1 -1
  34. package/src/repluggableAppDebug/repluggableAppDebug.ts +65 -43
  35. package/test/repluggableAppDebug.spec.ts +150 -0
  36. package/test/testKit.spec.tsx +57 -2
  37. package/testKit/index.ts +71 -18
package/testKit/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import _ from 'lodash'
2
2
  import { EntryPoint, ObservableState } from '../src/API'
3
3
  import { AnySlotKey, AppHost, createAppHost as _createAppHost, EntryPointOrPackage, Shell, SlotKey } from '../src/index'
4
+ import { UnreadyEntryPointsReport } from '../src/repluggableAppDebug'
4
5
  import { createShellLogger } from '../src/loggers'
5
6
  import { emptyLoggerOptions } from './emptyLoggerOptions'
6
7
 
@@ -81,34 +82,79 @@ export function createAppHostWithPacts(packages: EntryPointOrPackage[], pacts: P
81
82
  })
82
83
  }
83
84
 
84
- export async function createAppHostAndWaitForLoading(packages: EntryPointOrPackage[], pacts: PactAPIBase[]): Promise<AppHost> {
85
+ export interface WaitForLoadingOptions {
86
+ /** milliseconds to wait for host loading before rejecting with an unready entry points report (default: 3000) */
87
+ timeout?: number
88
+ }
89
+
90
+ export class AppHostLoadingTimeoutError extends Error {
91
+ constructor(message: string, public readonly report: UnreadyEntryPointsReport) {
92
+ super(message)
93
+ this.name = 'AppHostLoadingTimeoutError'
94
+ }
95
+ }
96
+
97
+ const WAIT_FOR_LOADING_PROBE_SHELL = 'Depends on all declared APIs'
98
+
99
+ const formatUnreadyReport = (timeout: number, report: UnreadyEntryPointsReport): string => {
100
+ const { utils } = globalThis.repluggableAppDebug
101
+ const isProbeShell = (name: string) => name === WAIT_FOR_LOADING_PROBE_SHELL
102
+ const header = `createAppHostAndWaitForLoading - host not ready within ${timeout}ms.`
103
+ const unreadyEntryPoints = report.unreadyEntryPoints.filter(entryPoint => !isProbeShell(entryPoint.name))
104
+ const rootUnreadyEntryPoints = report.rootUnreadyEntryPoints.filter(entryPoint => !isProbeShell(entryPoint.name))
105
+
106
+ if (report.probableDependencyCycle) {
107
+ const names = unreadyEntryPoints.map(entryPoint => `"${entryPoint.name}"`).join(', ')
108
+ return `${header}
109
+ No root unready API found while ${unreadyEntryPoints.length} entry points are unready - probable dependency cycle between: ${names}`
110
+ }
111
+
112
+ const roots = report.rootUnreadyAPIs.map((info, index) => {
113
+ const declaredBy =
114
+ info.declaredBy === 'nobody'
115
+ ? 'declared by NO entry point (missing package or pact?)'
116
+ : `declared by "${info.declaredBy.entryPointName}" (installed, but its contribution never completed - hung async contributeAPI?)`
117
+ const requiredBy = info.requiredBy.filter(name => !isProbeShell(name))
118
+ const lines = [`${index + 1}. "${info.key.name}" - ${declaredBy}`]
119
+ if (requiredBy.length) {
120
+ lines.push(` required by: ${requiredBy.join(', ')}`)
121
+ const tree = utils.visualizeDependencyTree(utils.traceAPIDependency(requiredBy[0], info.key.name))
122
+ lines.push(...tree.split('\n').map(line => ` ${line}`))
123
+ }
124
+ return lines.join('\n')
125
+ })
126
+
127
+ return `${header}
128
+
129
+ Root unready APIs (${report.rootUnreadyAPIs.length}):
130
+ ${roots.join('\n')}
131
+
132
+ Unready entry points: ${rootUnreadyEntryPoints.length} blocked directly on root APIs, ${unreadyEntryPoints.length} total.`
133
+ }
134
+
135
+ export async function createAppHostAndWaitForLoading(
136
+ packages: EntryPointOrPackage[],
137
+ pacts: PactAPIBase[],
138
+ { timeout = 3000 }: WaitForLoadingOptions = {}
139
+ ): Promise<AppHost> {
85
140
  const appHost = createAppHostWithPacts(packages, pacts)
86
141
  const declaredAPIs = _(packages)
87
142
  .flatten()
88
143
  .value()
89
144
  .flatMap((entryPoint: EntryPoint) => (entryPoint.declareAPIs ? entryPoint.declareAPIs() : []))
90
145
 
91
- const timeoutPromise = new Promise((resolve, reject) => {
92
- setTimeout(() => {
93
- const readyAPIs = Array.from(globalThis.repluggableAppDebug.readyAPIs)
94
- const unreadyAPIs = declaredAPIs.filter(api => !readyAPIs.some(readyAPI => readyAPI.name === api.name))
95
- const rootUnreadyAPI = globalThis.repluggableAppDebug.utils.getRootUnreadyAPI()
96
-
97
- reject(
98
- new Error(
99
- `createAppHostAndWaitForLoading - waiting for loading timed out.
100
- there's a high chance this missing API is the main reason for it: ${JSON.stringify(rootUnreadyAPI)}
101
-
102
- in addition here's the full list of declared APIs that have not been contributed: ${JSON.stringify(unreadyAPIs)}`
103
- )
104
- )
105
- }, 3000)
146
+ let timer: ReturnType<typeof setTimeout> | undefined
147
+ const timeoutPromise = new Promise<never>((resolve, reject) => {
148
+ timer = setTimeout(() => {
149
+ const report = globalThis.repluggableAppDebug.utils.getUnreadyEntryPointsReport()
150
+ reject(new AppHostLoadingTimeoutError(formatUnreadyReport(timeout, report), report))
151
+ }, timeout)
106
152
  })
107
153
 
108
154
  const loadingPromise = new Promise<void>(async resolve => {
109
155
  await appHost.addShells([
110
156
  {
111
- name: 'Depends on all declared APIs',
157
+ name: WAIT_FOR_LOADING_PROBE_SHELL,
112
158
  getDependencyAPIs() {
113
159
  return declaredAPIs
114
160
  },
@@ -119,7 +165,14 @@ in addition here's the full list of declared APIs that have not been contributed
119
165
  ])
120
166
  })
121
167
 
122
- return Promise.race([timeoutPromise, loadingPromise]).then(() => appHost)
168
+ try {
169
+ await Promise.race([timeoutPromise, loadingPromise])
170
+ return appHost
171
+ } finally {
172
+ if (timer) {
173
+ clearTimeout(timer)
174
+ }
175
+ }
123
176
  }
124
177
 
125
178
  type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>