@sitecore-feaas/clientside 0.1.19 → 0.1.21

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 (80) hide show
  1. package/build/basic.js +5 -1
  2. package/build/basic.js.map +1 -1
  3. package/build/cloud.js +40 -7
  4. package/build/cloud.js.map +1 -1
  5. package/build/components/FEAASBase.js +68 -29
  6. package/build/components/FEAASBase.js.map +1 -1
  7. package/build/components/FEAASComponent.js +36 -2
  8. package/build/components/FEAASComponent.js.map +1 -1
  9. package/build/components/FEAASElement.js +19 -0
  10. package/build/components/FEAASElement.js.map +1 -0
  11. package/build/components/FEAASLoader.js +13 -1
  12. package/build/components/FEAASLoader.js.map +1 -1
  13. package/build/components/FEAASStylesheet.js +1 -1
  14. package/build/components/FEAASStylesheet.js.map +1 -1
  15. package/build/dom.js +6 -0
  16. package/build/dom.js.map +1 -1
  17. package/build/fetch.js +48 -45
  18. package/build/fetch.js.map +1 -1
  19. package/build/ui/FEAASContext.js +13 -14
  20. package/build/ui/FEAASContext.js.map +1 -1
  21. package/build/ui/FEAASEditor.js +448 -76
  22. package/build/ui/FEAASEditor.js.map +1 -1
  23. package/build/ui/FEAASPicker.js +9 -59
  24. package/build/ui/FEAASPicker.js.map +1 -1
  25. package/dist/browser/basic.esm.js +5 -5
  26. package/dist/browser/basic.esm.js.map +1 -1
  27. package/dist/browser/basic.js +5 -5
  28. package/dist/browser/basic.js.map +1 -1
  29. package/dist/browser/index.esm.js +5 -10
  30. package/dist/browser/index.esm.js.map +1 -1
  31. package/dist/browser/index.js +5 -10
  32. package/dist/browser/index.js.map +1 -1
  33. package/dist/node/basic.esm.js +3 -3
  34. package/dist/node/basic.esm.js.map +1 -1
  35. package/dist/node/basic.js +3 -3
  36. package/dist/node/basic.js.map +1 -1
  37. package/dist/node/index.esm.js +3 -8
  38. package/dist/node/index.esm.js.map +1 -1
  39. package/dist/node/index.js +3 -8
  40. package/dist/node/index.js.map +1 -1
  41. package/examples/index.html +8 -49
  42. package/package.json +1 -6
  43. package/src/basic.ts +8 -1
  44. package/src/cloud.ts +43 -13
  45. package/src/components/FEAASBase.tsx +82 -32
  46. package/src/components/{FEAASComponent.ts → FEAASComponent.tsx} +38 -2
  47. package/src/components/FEAASElement.tsx +32 -0
  48. package/src/components/{FEAASLoader.ts → FEAASLoader.tsx} +14 -1
  49. package/src/components/{FEAASStylesheet.ts → FEAASStylesheet.tsx} +1 -1
  50. package/src/dom.ts +5 -0
  51. package/src/fetch.ts +82 -51
  52. package/src/ui/FEAASContext.tsx +14 -15
  53. package/src/ui/FEAASEditor.tsx +599 -145
  54. package/src/ui/FEAASPicker.tsx +19 -66
  55. package/test/components.ts +19 -0
  56. package/types/basic.d.ts +3 -0
  57. package/types/basic.d.ts.map +1 -1
  58. package/types/cloud.d.ts +8 -1
  59. package/types/cloud.d.ts.map +1 -1
  60. package/types/components/FEAASBase.d.ts +20 -6
  61. package/types/components/FEAASBase.d.ts.map +1 -1
  62. package/types/components/FEAASComponent.d.ts +8 -1
  63. package/types/components/FEAASComponent.d.ts.map +1 -1
  64. package/types/components/FEAASElement.d.ts +21 -0
  65. package/types/components/FEAASElement.d.ts.map +1 -0
  66. package/types/components/FEAASLoader.d.ts +6 -0
  67. package/types/components/FEAASLoader.d.ts.map +1 -1
  68. package/types/components/FEAASStylesheet.d.ts +3 -3
  69. package/types/components/FEAASStylesheet.d.ts.map +1 -1
  70. package/types/dom.d.ts.map +1 -1
  71. package/types/fetch.d.ts +42 -1
  72. package/types/fetch.d.ts.map +1 -1
  73. package/types/tsbuildinfo +1 -1
  74. package/types/tsbuildinfo_ui +1 -1
  75. package/types/ui/FEAASContext.d.ts +4 -4
  76. package/types/ui/FEAASContext.d.ts.map +1 -1
  77. package/types/ui/FEAASEditor.d.ts +70 -4
  78. package/types/ui/FEAASEditor.d.ts.map +1 -1
  79. package/types/ui/FEAASPicker.d.ts +14 -33
  80. package/types/ui/FEAASPicker.d.ts.map +1 -1
package/src/fetch.ts CHANGED
@@ -1,64 +1,95 @@
1
- /* Utility to cache-bust static files.
2
-
3
- It handles multiple situations:
4
-
5
- 1. Initial request, valid response
6
- 2. Initial request, invalid response
7
- 2. Initial request, missing response
8
- 3. Cached request, valid response (1 extra head request)
9
- 4. Cached request, invalid response, valid refetch (2 fetches + 1 head)
10
- 5. Cached request, invalid response, invalid refetch (2 fetches + 1 head)
11
-
12
- It works as promise, but also accepts callback to use cached blobs mid-flight and have access to headers.
13
- Any network errors will not caught.
14
- Function throws when unable to fetch valid response.
1
+ /**
2
+ * Utility to cache-bust static files. It relies on reading Date header to detect cached response, so it requires CORS
3
+ * settings to be set.
4
+ *
5
+ * It accepts validator function that determines if response is usable. If response was pulled from cache and is valid,
6
+ * the optional callback function is fired right away. Then HEAD request is made bypassing the cache, to see if the
7
+ * response has an newer Last-Modified header. In case it does and it passes validation, third request is fired that
8
+ * actually fetches the new content and callback is invoked the second time.
9
+ *
10
+ * It works as promise, but also accepts callback to use cached blobs mid-flight and have access to headers. Any network
11
+ * errors will not be caught. Function throws when unable to fetch valid response.
12
+ */
13
+ export interface ValidatableRequest {
14
+ url: Parameters<typeof fetch>[0]
15
+ options?: Parameters<typeof fetch>[1]
16
+ validator?: (resposne: Response) => boolean
17
+ callback?: (response: Response, status: 'initial' | 'updated' | 'check') => void
18
+ isCached?: boolean
19
+ response?: Response
20
+ }
15
21
 
16
- */
17
22
  export async function fetchAndRevalidate(
18
- url: Parameters<typeof fetch>[0],
19
- options: Parameters<typeof fetch>[1],
20
- validator: (resposne: Response) => boolean,
21
- callback: (response: Response, status: 'cached' | 'valid') => void
23
+ url: ValidatableRequest['url'],
24
+ options?: ValidatableRequest['options'],
25
+ validator?: ValidatableRequest['validator'],
26
+ callback?: ValidatableRequest['callback']
22
27
  ) {
23
28
  // make request as usual, see if there's cached version of an asset
24
- const date = new Date()
25
- const initialResponse = await fetch(url, options)
26
- if (!initialResponse.ok) throw new Error('Fetch failed')
27
- const responseDate = new Date(initialResponse.headers.get('date'))
28
- var response = initialResponse
29
- callback(initialResponse, 'cached')
29
+ return fetchAndValidate({ url, options, validator, callback })
30
+ .then(refetchAndValidate)
31
+ .then((result) => result.response)
32
+ }
30
33
 
34
+ export async function fetchAndValidate(
35
+ { url, options, validator, callback }: ValidatableRequest,
36
+ phase: 'initial' | 'updated' | 'check' = 'initial'
37
+ ) {
38
+ const date = new Date()
39
+ console.log('fetch', phase, url)
40
+ const response = await fetch(url, options)
41
+ if (!response.ok) throw new Error('Fetch failed')
42
+ if (validator?.(response) === false) throw new Error('Response is not valid')
31
43
  // see if response was pulled from cache
32
- if (responseDate < date) {
33
- // check if response was stale by sending quick HEAD reque st busting cache
34
- const freshHeadResponse = await fetch(url + '?' + Math.random(), {
35
- ...options,
36
- method: 'HEAD',
37
- cache: 'no-cache'
38
- })
44
+ const isCached = new Date(response.headers.get('date')) < date
45
+ callback?.(response, phase)
46
+ return {
47
+ url,
48
+ options,
49
+ isCached,
50
+ response,
51
+ validator
52
+ }
53
+ }
39
54
 
40
- // there's a newer version of the file that we may fetch
41
- if (freshHeadResponse.headers.get('last-modified') != initialResponse.headers.get('last-modified')) {
42
- // check if re-fetching is even necessary
43
- if (validator(freshHeadResponse) === false) {
44
- //callback('stale', freshHeadResponse)
45
- throw new Error('Response is stale')
46
- }
55
+ export async function refetchAndValidate(request: ValidatableRequest & Required<Pick<ValidatableRequest, 'response'>>) {
56
+ const { url, isCached, options, validator, response, callback } = request
57
+ if (isCached) {
58
+ // check if response was stale by sending quick HEAD request busting cache
59
+ const { response: head } = await fetchAndValidate(
60
+ {
61
+ url: url + '?' + Math.random(),
62
+ options: {
63
+ ...options,
64
+ method: 'HEAD',
65
+ cache: 'no-cache'
66
+ },
67
+ validator
68
+ },
69
+ 'check'
70
+ )
47
71
 
72
+ // there's a newer version of the file that we may fetch
73
+ if (head.headers.get('last-modified') != response.headers.get('last-modified')) {
48
74
  // otherwise the new resource has to be re-fetched
49
- response = await fetch(url, {
50
- ...options,
51
- cache: 'reload'
52
- })
75
+ return invalidateRequest(request)
53
76
  }
54
77
  }
78
+ return request
79
+ }
55
80
 
56
- if (validator(response) === false) {
57
- throw new Error('Response is not valid')
58
- }
59
- if (initialResponse !== response) {
60
- callback(response, 'valid')
61
- }
62
-
63
- return response
81
+ export async function invalidateRequest(request: ValidatableRequest) {
82
+ const { url, options, validator, callback } = request
83
+ return fetchAndValidate(
84
+ {
85
+ url,
86
+ options: {
87
+ ...options,
88
+ cache: 'reload'
89
+ },
90
+ validator,
91
+ callback
92
+ },
93
+ 'updated'
94
+ )
64
95
  }
@@ -4,7 +4,7 @@ import { FEAASBase, OptionalExcept } from '../components/FEAASBase.js'
4
4
  export function FEAASContextProps(element: HTMLElement = this) {
5
5
  return {
6
6
  library: element?.getAttribute('library') as string,
7
- src: element?.getAttribute('src') ?? '/assets/context.js',
7
+ src: element?.getAttribute('src') ?? '/context.js',
8
8
  frontend: element?.getAttribute('frontend') ?? 'https://components.sitecoreclud.io',
9
9
  backend: element?.getAttribute('backend') ?? 'https://components-api.sitecoreclud.io',
10
10
  cdn: element?.getAttribute('cdn') ?? 'https://feaascompontsapiprod.blob.core.windows.net',
@@ -36,26 +36,24 @@ export class FEAASContext extends FEAASBase<FEAASContextProps, typeof FEAASConte
36
36
  return this.shadowRoot || this.attachShadow({ mode: 'open' })
37
37
  }
38
38
 
39
- reactRoot: HTMLDivElement
40
- getReactRoot() {
41
- if (!this.reactRoot) {
42
- this.reactRoot = document.createElement('div')
43
- this.getRoot().appendChild(this.reactRoot)
39
+ reactRootElement: HTMLDivElement
40
+ getReactRootElement() {
41
+ if (!this.reactRootElement) {
42
+ this.reactRootElement = document.createElement('div')
43
+ this.getRoot().appendChild(this.reactRootElement)
44
44
  }
45
- return this.reactRoot
45
+ return this.reactRootElement
46
46
  }
47
47
 
48
48
  /** Pull in children FEAAS react elements into the shadow DOM so they receieve the styles */
49
- nestedCallback(event: Event) {
50
- super.nestedCallback(event)
51
-
52
- const target = event.composedPath()[0] as FEAASBase
53
- if (target.parentNode != this.getRoot()) {
54
- this.getRoot().appendChild(target)
55
- }
49
+ connectedCallback(): void {
50
+ Array.from(this.children).forEach((child) => {
51
+ this.getRoot().appendChild(child)
52
+ })
53
+ super.connectedCallback()
56
54
  }
57
55
 
58
- renderReact(
56
+ render(
59
57
  { children, library }: React.PropsWithChildren<FEAASContextProps>,
60
58
  { AppContext, Chakra: { Button, Tooltip }, React }: typeof this.payload
61
59
  ) {
@@ -69,6 +67,7 @@ export class FEAASContext extends FEAASBase<FEAASContextProps, typeof FEAASConte
69
67
  }
70
68
  return (
71
69
  <AppContext
70
+ backend={this.props.backend}
72
71
  libraryId={this.props.library}
73
72
  container={this.getRoot()}
74
73
  getToken={this.props.getToken}