@sitecore-feaas/clientside 0.2.0 → 0.2.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.
Files changed (120) hide show
  1. package/README.md +56 -36
  2. package/build/components/FEAASComponent.js +71 -11
  3. package/build/components/FEAASComponent.js.map +1 -1
  4. package/build/components/FEAASElement.js +411 -37
  5. package/build/components/FEAASElement.js.map +1 -1
  6. package/build/components/FEAASLoader.js +2 -2
  7. package/build/components/FEAASLoader.js.map +1 -1
  8. package/build/components/FEAASReactElement.js +47 -0
  9. package/build/components/FEAASReactElement.js.map +1 -0
  10. package/build/components/FEAASStylesheet.js +2 -2
  11. package/build/components/FEAASStylesheet.js.map +1 -1
  12. package/build/headless.js +4 -3
  13. package/build/headless.js.map +1 -1
  14. package/build/ui/FEAAS.js +5 -0
  15. package/build/ui/FEAAS.js.map +1 -0
  16. package/build/ui/FEAASContext.js +20 -8
  17. package/build/ui/FEAASContext.js.map +1 -1
  18. package/build/ui/FEAASEditor.js +2 -2
  19. package/build/ui/FEAASEditor.js.map +1 -1
  20. package/build/ui/FEAASExternal.js +128 -24
  21. package/build/ui/FEAASExternal.js.map +1 -1
  22. package/build/ui/FEAASPicker.js +7 -2
  23. package/build/ui/FEAASPicker.js.map +1 -1
  24. package/build/ui/index.js +3 -4
  25. package/build/ui/index.js.map +1 -1
  26. package/build/ui/react.js.map +1 -1
  27. package/build/utils/fetch.js +26 -0
  28. package/build/utils/fetch.js.map +1 -0
  29. package/dist/browser/headless.cjs +6 -6
  30. package/dist/browser/headless.cjs.map +4 -4
  31. package/dist/browser/headless.esm.js +6 -6
  32. package/dist/browser/headless.esm.js.map +1 -1
  33. package/dist/browser/index.cjs +7 -7
  34. package/dist/browser/index.cjs.map +4 -4
  35. package/dist/browser/index.esm.js +7 -7
  36. package/dist/browser/index.esm.js.map +1 -1
  37. package/dist/browser/react.cjs +6 -6
  38. package/dist/browser/react.cjs.map +4 -4
  39. package/dist/browser/react.esm.js +6 -6
  40. package/dist/browser/react.esm.js.map +1 -1
  41. package/dist/node/headless.cjs +4 -4
  42. package/dist/node/headless.cjs.map +4 -4
  43. package/dist/node/headless.esm.js +4 -4
  44. package/dist/node/headless.esm.js.map +4 -4
  45. package/dist/node/index.cjs +4 -4
  46. package/dist/node/index.cjs.map +4 -4
  47. package/dist/node/index.esm.js +4 -4
  48. package/dist/node/index.esm.js.map +4 -4
  49. package/dist/node/react.cjs +4 -4
  50. package/dist/node/react.cjs.map +4 -4
  51. package/dist/node/react.esm.js +4 -4
  52. package/dist/node/react.esm.js.map +4 -4
  53. package/headless.cjs +4 -4
  54. package/headless.cjs.map +4 -4
  55. package/headless.js +4 -4
  56. package/headless.js.map +4 -4
  57. package/package.json +11 -3
  58. package/react.cjs +6 -6
  59. package/react.cjs.map +4 -4
  60. package/react.js +6 -6
  61. package/react.js.map +4 -4
  62. package/scripts/build.js +1 -1
  63. package/scripts/test-setup.ts +1 -0
  64. package/src/components/FEAASComponent.tsx +96 -12
  65. package/src/components/FEAASElement.tsx +479 -41
  66. package/src/components/FEAASLoader.tsx +2 -2
  67. package/src/components/FEAASReactElement.tsx +61 -0
  68. package/src/components/FEAASStylesheet.tsx +3 -3
  69. package/src/headless.ts +5 -4
  70. package/src/ui/FEAAS.tsx +4 -0
  71. package/src/ui/FEAASContext.tsx +25 -7
  72. package/src/ui/FEAASEditor.tsx +7 -7
  73. package/src/ui/FEAASExternal.tsx +134 -24
  74. package/src/ui/FEAASPicker.tsx +9 -5
  75. package/src/ui/index.ts +4 -4
  76. package/src/ui/react.tsx +5 -0
  77. package/src/ui/tsconfig.json +1 -1
  78. package/src/utils/fetch.ts +44 -0
  79. package/test/FEAASBase.test.tsx +2 -2
  80. package/test/FEAASComponent.test.tsx +4 -1
  81. package/test/FEAASComponent2.test.tsx +215 -0
  82. package/test/FEAASContext.test.tsx +206 -29
  83. package/test/FEAASExternal.test.tsx +1 -8
  84. package/test/FEAASPicker.test.tsx +4 -2
  85. package/test/fetch-data.ts +55 -0
  86. package/types/components/FEAASComponent.d.ts +33 -3
  87. package/types/components/FEAASComponent.d.ts.map +1 -1
  88. package/types/components/FEAASElement.d.ts +299 -22
  89. package/types/components/FEAASElement.d.ts.map +1 -1
  90. package/types/components/FEAASLoader.d.ts +2 -2
  91. package/types/components/FEAASLoader.d.ts.map +1 -1
  92. package/types/components/FEAASReactElement.d.ts +30 -0
  93. package/types/components/FEAASReactElement.d.ts.map +1 -0
  94. package/types/components/FEAASStylesheet.d.ts +3 -3
  95. package/types/components/FEAASStylesheet.d.ts.map +1 -1
  96. package/types/headless.d.ts +4 -3
  97. package/types/headless.d.ts.map +1 -1
  98. package/types/tsbuildinfo +1 -1
  99. package/types/ui/FEAAS.d.ts +5 -0
  100. package/types/ui/FEAAS.d.ts.map +1 -0
  101. package/types/ui/FEAASContext.d.ts +16 -7
  102. package/types/ui/FEAASContext.d.ts.map +1 -1
  103. package/types/ui/FEAASEditor.d.ts +6 -6
  104. package/types/ui/FEAASEditor.d.ts.map +1 -1
  105. package/types/ui/FEAASExternal.d.ts +59 -10
  106. package/types/ui/FEAASExternal.d.ts.map +1 -1
  107. package/types/ui/FEAASPicker.d.ts +11 -9
  108. package/types/ui/FEAASPicker.d.ts.map +1 -1
  109. package/types/ui/index.d.ts +1 -4
  110. package/types/ui/index.d.ts.map +1 -1
  111. package/types/ui/react.d.ts.map +1 -1
  112. package/types/ui/tsbuildinfo +1 -0
  113. package/types/utils/fetch.d.ts +9 -0
  114. package/types/utils/fetch.d.ts.map +1 -0
  115. package/build/components/FEAASBase.js +0 -416
  116. package/build/components/FEAASBase.js.map +0 -1
  117. package/src/components/FEAASBase.tsx +0 -485
  118. package/types/components/FEAASBase.d.ts +0 -299
  119. package/types/components/FEAASBase.d.ts.map +0 -1
  120. package/types/tsbuildinfo_ui +0 -1
package/scripts/build.js CHANGED
@@ -3,6 +3,7 @@ import * as esbuild from 'esbuild'
3
3
  import replace from 'esbuild-plugin-replace-regex'
4
4
  import * as url from 'url'
5
5
  import fs from 'fs'
6
+
6
7
  const __filename = url.fileURLToPath(import.meta.url)
7
8
  const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
8
9
 
@@ -17,7 +18,6 @@ function compile({ input, output, ...step }) {
17
18
  bundle: true,
18
19
  write: false,
19
20
  external: ['node:crypto', 'node-fetch', '_MAGIC_IMPORT_COMMENTS_ESBUILD_WORKAROUND__', 'react', 'react-dom', 'vm'],
20
-
21
21
  ...step,
22
22
 
23
23
  minify: true,
@@ -1 +1,2 @@
1
+ process.env.TESTING = 'true'
1
2
  export default function () {}
@@ -1,9 +1,11 @@
1
1
  import { DEFAULT_CDN_URL, FEAASCDNComponentParams, fetchAndRevalidateComponent, parseComponentSource } from '../cdn.js'
2
2
  import { renderDOMContent, renderDOMElement } from '../dom/rendering.js'
3
3
  import { loadStylesheetAllowStale } from '../headless.js'
4
- import { FEAASBase } from './FEAASBase.js'
4
+ import { ControlledPromise } from '../utils/promise.js'
5
+ import { fetchData } from '../utils/fetch.js'
6
+ import { FEAASElement } from './FEAASElement.js'
5
7
 
6
- export function FEAASComponentsProps(element: FEAASBase) {
8
+ export function FEAASComponentsProps(element: FEAASElement) {
7
9
  let data: any
8
10
  const src = element.getAttribute('src')
9
11
  if (src) {
@@ -33,8 +35,40 @@ export function FEAASComponentsProps(element: FEAASBase) {
33
35
  withStylesheet: element.getAttribute('with-stylesheet') != 'false'
34
36
  }
35
37
  }
38
+
36
39
  export type FEAASComponentsProps = ReturnType<typeof FEAASComponentsProps>
37
- export class FEAASComponent extends FEAASBase<FEAASComponentsProps, string> {
40
+
41
+ /**
42
+ * - Initialization lifecycle:
43
+ * - - `set(props)`
44
+ * - - `scheduleRender()` - any attribute change causes render to schedule to next frame
45
+ * - - `whenRendered.restart()` - rendering promise is reset and will resolve after render
46
+ * - - `advance()` - called on next frame
47
+ * - - `if (isReadyToLoad()) => boolean` - check if component has all necessary properties to load
48
+ * - - `load() => payload` => component is loaded
49
+ * - - `onLoad?(payload)` => invoke loaded callback for cached version of a component
50
+ * - - `advance()` => going further in state machine
51
+ * - - `flush()` => flushes all react changes if needed
52
+ * - - `update()` => component-specific method (or react) to render changes to dom
53
+ * - - `render(payload, props)` => render means react
54
+ * - - `whenRendered.resolve()` - rendering promise is resolved after rendering
55
+ * - - IF CACHE WAS STALE - FETCH AND RENDER AGAIN
56
+ * - - `fetchByPassingCache()` - load up-to-date version of a component
57
+ * - - `onLoad(newPayload) `
58
+ * - - `advance()` => going further in state machine
59
+ * - - `flush()` => flushes all react changes if needed
60
+ * - - `update()` => component-specific method (or react) to render changes to dom
61
+ * - - `render(payload, props)` => render means react
62
+ * - - `whenRendered.resolve()` - rendering promise is resolved after rendering
63
+ * - - `whenLoaded.resolved()` - resolved after loading of up to date component
64
+ */
65
+ export class FEAASComponent extends FEAASElement<FEAASComponentsProps, string> {
66
+ readyData: any = {}
67
+ whenDataReady = ControlledPromise<any>(
68
+ (data) => (this.readyData = data),
69
+ (e) => this.onError(e)
70
+ )
71
+
38
72
  static observedAttributes = [
39
73
  'library',
40
74
  'component',
@@ -59,6 +93,7 @@ export class FEAASComponent extends FEAASBase<FEAASComponentsProps, string> {
59
93
  } as Partial<FEAASComponentsProps>
60
94
 
61
95
  needsRefresh: boolean
96
+
62
97
  setData(data: any) {
63
98
  this.set({ data })
64
99
  }
@@ -69,20 +104,47 @@ export class FEAASComponent extends FEAASBase<FEAASComponentsProps, string> {
69
104
 
70
105
  attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
71
106
  if (oldValue === newValue) return
107
+
72
108
  // force component to be refreshed
73
109
  if (name == 'library' || name == 'component' || name == 'revision' || name == 'version') {
74
110
  this.payload = undefined
75
111
  }
112
+
76
113
  this.needsRefresh = true
114
+
77
115
  super.attributeChangedCallback(name, oldValue, newValue)
116
+
117
+ if (name === 'data') {
118
+ this.fetchData()
119
+ }
120
+ }
121
+
122
+ // Reset readyData and perform a new fetch.
123
+ async fetchData() {
124
+ this.readyData = undefined
125
+
126
+ this.whenDataReady = this.whenDataReady.restart()
127
+
128
+ const data = await fetchData(this.props.data)
129
+ const alreadyRendered = this.alreadyRendered
130
+
131
+ await this.whenDataReady.resolve(data)
132
+ if (alreadyRendered) {
133
+ this.advance()
134
+ }
78
135
  }
79
136
 
80
137
  getEditor(): any {
81
- return (document.querySelector('feaas-context') as FEAASBase)?.refs.editor
138
+ return (document.querySelector('feaas-context') as FEAASElement)?.refs.editor
82
139
  }
83
140
 
84
141
  constructor() {
85
142
  super()
143
+
144
+ if (!this.getAttribute('data')) {
145
+ this.whenDataReady.resolve({})
146
+ }
147
+
86
148
  this.addEventListener('click', () => {
87
149
  if (this.props.editable) {
88
150
  this.edit()
@@ -125,36 +187,58 @@ export class FEAASComponent extends FEAASBase<FEAASComponentsProps, string> {
125
187
 
126
188
  async load() {
127
189
  // defer loading to original element
128
- if (this.getOriginal()) {
129
- return
190
+ if (this.getOriginal()) return
191
+
192
+ const advanceIfEverythingIsReady = () => {
193
+ // html is not loaded
194
+ if (!this.payload) return
195
+
196
+ // shared stylesheet is still being loaded
197
+ if (stylesheetPromise) return
198
+
199
+ // data is still loading
200
+ if (!this.readyData) return
201
+
202
+ this.onLoad(this.payload)
130
203
  }
204
+
131
205
  if (this.props.withStylesheet) {
132
206
  var stylesheetPromise = loadStylesheetAllowStale({ ...this.props, revision: 'published' }).then(() => {
133
207
  stylesheetPromise = null
134
- if (this.payload) {
135
- this.onLoad(this.payload)
136
- }
208
+ advanceIfEverythingIsReady()
137
209
  })
138
210
  }
211
+
139
212
  return Promise.all([
140
213
  stylesheetPromise,
214
+ this.whenDataReady.then(() => advanceIfEverythingIsReady()),
141
215
  fetchAndRevalidateComponent(this.props, (html) => {
142
216
  this.payload = html
143
- if (!stylesheetPromise) this.onLoad(html)
217
+ advanceIfEverythingIsReady()
144
218
  })
145
219
  ]).then(() => this.payload)
146
220
  }
147
221
 
222
+ alreadyRendered: boolean
223
+
224
+ flush() {
225
+ if (!this.readyData) return
226
+
227
+ super.flush()
228
+ }
229
+
148
230
  update() {
231
+ this.alreadyRendered = true
232
+
149
233
  if (Array.from(this.children).filter((c) => c.tagName != 'BR').length > 0 && !this.needsRefresh) {
150
- renderDOMElement(this, this.props.data)
234
+ renderDOMElement(this, this.readyData)
151
235
  } else {
152
236
  this.needsRefresh = true
153
237
  // defer rendering to original element
154
238
  if (this.getOriginal()) {
155
239
  return
156
240
  }
157
- renderDOMContent(this, this.payload, this.props.data)
241
+ renderDOMContent(this, this.payload, this.readyData)
158
242
  }
159
243
  }
160
244
  }