@sitecore-feaas/clientside 0.1.25 → 0.1.28

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 (65) hide show
  1. package/build/basic.js +1 -0
  2. package/build/basic.js.map +1 -1
  3. package/build/cloud.js +9 -1
  4. package/build/cloud.js.map +1 -1
  5. package/build/components/FEAASComponent.js +5 -5
  6. package/build/components/FEAASComponent.js.map +1 -1
  7. package/build/components/FEAASElement.js +2 -3
  8. package/build/components/FEAASElement.js.map +1 -1
  9. package/build/components/FEAASLoader.js +1 -2
  10. package/build/components/FEAASLoader.js.map +1 -1
  11. package/build/dom.js +29 -6
  12. package/build/dom.js.map +1 -1
  13. package/build/node.js +10 -0
  14. package/build/node.js.map +1 -0
  15. package/build/ui/node.js +3 -0
  16. package/build/ui/node.js.map +1 -0
  17. package/dist/browser/basic.esm.js +5 -5
  18. package/dist/browser/basic.esm.js.map +1 -1
  19. package/dist/browser/basic.js +5 -5
  20. package/dist/browser/basic.js.map +1 -1
  21. package/dist/browser/index.esm.js +5 -5
  22. package/dist/browser/index.esm.js.map +1 -1
  23. package/dist/browser/index.js +5 -5
  24. package/dist/browser/index.js.map +1 -1
  25. package/dist/node/basic.esm.js +4 -4
  26. package/dist/node/basic.esm.js.map +7 -1
  27. package/dist/node/basic.js +4 -4
  28. package/dist/node/basic.js.map +7 -1
  29. package/dist/node/index.esm.js +4 -4
  30. package/dist/node/index.esm.js.map +7 -1
  31. package/dist/node/index.js +4 -4
  32. package/dist/node/index.js.map +7 -1
  33. package/package.json +18 -10
  34. package/scripts/build.js +1 -1
  35. package/src/basic.ts +1 -0
  36. package/src/cloud.ts +20 -1
  37. package/src/components/FEAASBase.tsx +1 -1
  38. package/src/components/FEAASComponent.tsx +6 -3
  39. package/src/components/FEAASElement.tsx +1 -1
  40. package/src/dom.ts +28 -5
  41. package/src/node.ts +10 -0
  42. package/src/ui/node.ts +2 -0
  43. package/test/render.ts +91 -93
  44. package/types/basic.d.ts +1 -0
  45. package/types/basic.d.ts.map +1 -1
  46. package/types/cloud.d.ts +15 -2
  47. package/types/cloud.d.ts.map +1 -1
  48. package/types/components/FEAASComponent.d.ts +6 -0
  49. package/types/components/FEAASComponent.d.ts.map +1 -1
  50. package/types/dom.d.ts +1 -0
  51. package/types/dom.d.ts.map +1 -1
  52. package/types/fetch.d.ts +2 -2
  53. package/types/fetch.d.ts.map +1 -1
  54. package/types/node.d.ts +4 -0
  55. package/types/node.d.ts.map +1 -0
  56. package/types/tsbuildinfo +1 -1
  57. package/types/tsbuildinfo_ui +1 -1
  58. package/types/ui/FEAASContext.d.ts +1 -1
  59. package/types/ui/FEAASContext.d.ts.map +1 -1
  60. package/types/ui/FEAASEditor.d.ts +2 -2
  61. package/types/ui/FEAASEditor.d.ts.map +1 -1
  62. package/types/ui/FEAASPicker.d.ts +1 -1
  63. package/types/ui/FEAASPicker.d.ts.map +1 -1
  64. package/types/ui/node.d.ts +3 -0
  65. package/types/ui/node.d.ts.map +1 -0
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@sitecore-feaas/clientside",
3
- "version": "0.1.25",
3
+ "version": "0.1.28",
4
4
  "scripts": {
5
5
  "start": "webpack serve --open",
6
6
  "build": "rm -rf dist;npm run types; npm run build:esbuild; npm run build:sourcemaps",
7
7
  "build:esbuild": "node scripts/build.js",
8
- "build:sourcemaps": "npx merge-source-maps dist/**/*.js --inline-sources",
8
+ "build:sourcemaps": "npx merge-source-maps dist/browser/*.js --inline-sources",
9
9
  "test": "npx vitest --config ../frontend/vite.config.ts",
10
10
  "test:watch": "npx vitest --config ../frontend/vite.config.ts",
11
11
  "prepublishOnly": "npm run build",
@@ -17,27 +17,31 @@
17
17
  "peerDependencies": {
18
18
  "react-dom": ">=16.8.0"
19
19
  },
20
- "main": "./dist/browser/index.esm.js",
21
- "browser": "./dist/browser/index.esm.js",
20
+ "main": "./dist/node/index.js",
21
+ "browser": "./dist/browser/index.js",
22
22
  "module": "./dist/node/index.esm.js",
23
23
  "types": "./types/ui/index.d.js",
24
24
  "type": "module",
25
25
  "exports": {
26
26
  ".": {
27
- "development": "./build/ui/index.js",
27
+ "localhost": "./build/ui/index.js",
28
28
  "types": "./types/ui/index.d.ts",
29
+ "browser": "./dist/browser/index.esm.js",
30
+ "import": "./dist/node/index.esm.js",
29
31
  "require": "./dist/node/index.js",
32
+ "default": "./dist/node/index.esm.js"
33
+ },
34
+ "./server": {
30
35
  "import": "./dist/node/index.esm.js",
31
- "browser": "./dist/browser/index.esm.js",
32
36
  "default": "./dist/node/index.js"
33
37
  },
34
38
  "./basic": {
35
- "development": "./build/basic.js",
39
+ "localhost": "./build/basic.js",
36
40
  "types": "./types/basic.d.ts",
37
- "require": "./dist/node/basic.js",
38
- "import": "./dist/node/basic.esm.js",
39
41
  "browser": "./dist/browser/basic.esm.js",
40
- "default": "./dist/node/basic.js"
42
+ "import": "./dist/node/inbasicdex.esm.js",
43
+ "require": "./dist/node/basic.js",
44
+ "default": "./dist/node/basic.esm.js"
41
45
  }
42
46
  },
43
47
  "typedoc": {
@@ -49,7 +53,11 @@
49
53
  "@types/jsonpath-plus": "^5.0.2",
50
54
  "esbuild": "^0.16.17",
51
55
  "esbuild-plugin-replace-regex": "^0.0.2",
56
+ "htmlparser2": "^8.0.1",
52
57
  "jsonpath-plus": "^7.2.0",
53
58
  "merge-source-maps": "^0.6.1"
59
+ },
60
+ "dependencies": {
61
+ "linkedom": "^0.14.22"
54
62
  }
55
63
  }
package/scripts/build.js CHANGED
@@ -16,7 +16,7 @@ function compile({ input, output, ...step }) {
16
16
  outfile: path.resolve(__dirname, '../' + output),
17
17
  bundle: true,
18
18
  write: false,
19
- external: ['node:crypto', 'node-fetch', 'MAGIC_IMPORT_COMMENTS_ESBUILD_WORKAROUND'],
19
+ external: ['node:crypto', 'node-fetch', 'MAGIC_IMPORT_COMMENTS_ESBUILD_WORKAROUND', 'linkedom'],
20
20
 
21
21
  ...step,
22
22
 
package/src/basic.ts CHANGED
@@ -2,6 +2,7 @@ import FEAASElement from './components/FEAASElement.js'
2
2
 
3
3
  export * from './dom.js'
4
4
  export * from './fetch.js'
5
+ export * from './cloud.js'
5
6
  export * from './components/FEAASBase.js'
6
7
  export * from './components/FEAASElement.js'
7
8
  export * from './components/FEAASComponent.js'
package/src/cloud.ts CHANGED
@@ -8,6 +8,7 @@ export interface CloudTemplate {
8
8
  version: string
9
9
  revision?: string
10
10
  instance?: string
11
+ lastModified?: string | Date
11
12
  }
12
13
  export interface CloudStylesheet {
13
14
  cdn?: string
@@ -36,7 +37,11 @@ export function getStylesheetURL({
36
37
  return `${cdn || hostname}/styles/${library}/${revision}.css`
37
38
  }
38
39
 
39
- export async function fetchComponent(props: CloudTemplate, callback: (html: string) => void) {
40
+ export async function fetchAndRevalidateComponent(
41
+ props: CloudTemplate,
42
+ callback?: (html: string) => void,
43
+ dontRevalidate = false
44
+ ) {
40
45
  const onlyIfNotDeleted = (response: Response) => {
41
46
  return response.headers.get('x-ms-meta-versionDeletedAt') == null
42
47
  }
@@ -68,6 +73,7 @@ export async function fetchComponent(props: CloudTemplate, callback: (html: stri
68
73
  console.log('Using fork!', results)
69
74
  }
70
75
  parseResponse(result.response)
76
+
71
77
  return refetchAndValidate({ ...result, callback: parseResponse }).catch((e) => {
72
78
  if (results[0] == result) {
73
79
  invalidateRequest({ ...result, callback: null, validator: null })
@@ -82,6 +88,19 @@ export async function fetchComponent(props: CloudTemplate, callback: (html: stri
82
88
  })
83
89
  }
84
90
 
91
+ /** Fetches HTML of a component. */
92
+ export async function fetchComponent(props: CloudTemplate) {
93
+ var template: string
94
+ const { response } = await fetchAndRevalidateComponent(
95
+ props,
96
+ (result) => {
97
+ template = result
98
+ },
99
+ false
100
+ )
101
+ return { ...props, template, lastModified: response.headers.get('last-modified') }
102
+ }
103
+
85
104
  export async function fetchStylesheet(props: CloudStylesheet, callback: (css: string) => void) {
86
105
  return fetchAndRevalidate(
87
106
  getStylesheetURL(props),
@@ -260,7 +260,7 @@ export class FEAASBase<Props = any, Payload = any> extends WebComponent {
260
260
  * Render method that is pretty much the same as React Functional component, but with extra second argument for
261
261
  * payload (usually result of import, it is expected to have React in scope).
262
262
  */
263
- render?(props: React.PropsWithChildren<typeof this.props>, payload: typeof this.payload): ReactNode | ReactElement
263
+ render?(props: React.PropsWithChildren<Props>, payload: Payload): ReactNode | ReactElement
264
264
 
265
265
  useShadowRoot: boolean
266
266
  getShadowRoot() {
@@ -1,4 +1,4 @@
1
- import { fetchComponent } from '../cloud.js'
1
+ import { fetchAndRevalidateComponent } from '../cloud.js'
2
2
  import { renderDOMContent, renderDOMElement } from '../dom.js'
3
3
  import { FEAASBase, OptionalExcept } from './FEAASBase.js'
4
4
  import { FEAASLoader } from './FEAASLoader.js'
@@ -22,7 +22,8 @@ export function FEAASComponentsProps(element: FEAASBase = this) {
22
22
  template: element.getAttribute('template'),
23
23
  instance: element.getAttribute('instance'),
24
24
  editable: element.getAttribute('editable') != null,
25
- suspended: element.getAttribute('suspended') != null
25
+ suspended: element.getAttribute('suspended') != null,
26
+ lastModified: element.getAttribute('last-modified')
26
27
  }
27
28
  }
28
29
  export type FEAASComponentsProps = ReturnType<typeof FEAASComponentsProps>
@@ -103,7 +104,7 @@ export class FEAASComponent extends FEAASBase<FEAASComponentsProps, string> {
103
104
  return
104
105
  }
105
106
  try {
106
- fetchComponent(this.props, this.onLoad)
107
+ fetchAndRevalidateComponent(this.props, this.onLoad)
107
108
  } catch {
108
109
  console.error(
109
110
  `FEAAS: Could not fetch component: ${this.props.component}/${this.props.version}/${this.props.revision}`
@@ -130,6 +131,8 @@ declare global {
130
131
  interface IntrinsicElements {
131
132
  'feaas-component': OptionalExcept<FEAASComponentsProps, 'component' | 'version' | 'revision'> & {
132
133
  children?: any
134
+ dangerouslySetInnerHTML?: { __html: string }
135
+ 'last-modified'?: string
133
136
  }
134
137
  }
135
138
  }
@@ -13,7 +13,7 @@ export type FEAASReactRender<P> = {
13
13
  export default class FEAASElement<P> extends FEAASBase<P, ReactModules> {
14
14
  load() {
15
15
  return Promise.all([
16
- // @ts-ignore
16
+ // @ts-ignore @webpack-ignore
17
17
  import('https://cdn.skypack.dev/react'),
18
18
  // @ts-ignore
19
19
  import('https://cdn.skypack.dev/react-dom')
package/src/dom.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { JSONPath } from 'jsonpath-plus'
2
- import { CloudStylesheet, CloudTemplate, fetchComponent, fetchStylesheet } from './cloud.js'
2
+ import { CloudStylesheet, CloudTemplate, fetchAndRevalidateComponent, fetchStylesheet } from './cloud.js'
3
3
 
4
4
  export interface FEAASCustomizations {
5
5
  processTemplate?: (element: HTMLElement, template: string, data: any) => string
@@ -300,14 +300,19 @@ export function renderDOMElement(
300
300
  }
301
301
  }
302
302
  }
303
- for (var i = 0; i < element.children.length; i++) {
304
- renderDOMElement(<HTMLElement>element.children[i], datascopes, config, true)
303
+ for (var i = 0, child: Node; (child = element.childNodes[i++]); ) {
304
+ if (isElement(child)) {
305
+ renderDOMElement(child, datascopes, config, true)
306
+ }
305
307
  }
306
308
  if (!isNested) {
307
309
  config?.onRender?.(element, datascopes)
308
310
  }
309
311
  return element
310
312
  }
313
+ function isElement(node: Node): node is HTMLElement {
314
+ return node.nodeType == 1
315
+ }
311
316
 
312
317
  export function renderDOMContent(root: HTMLElement, template: string, data?: Datascopes, config?: FEAASCustomizations) {
313
318
  const newTemplate = config?.processTemplate?.(root, template, data) || template
@@ -316,11 +321,29 @@ export function renderDOMContent(root: HTMLElement, template: string, data?: Dat
316
321
  // fixme, jss needs to assign theme classes to component instead
317
322
  const anchor = root.closest('.component.feaas') || root
318
323
  if (anchor.className.includes('-theme--')) {
319
- for (const child of root.children) child.className = child.className.replace(/(\s|^)-theme--[^\s]+\s*/g, '$1')
324
+ for (var i = 0, child: Node; (child = root.childNodes[i++]); ) {
325
+ if (isElement(child)) {
326
+ child.className = child.className.replace(/(\s|^)-theme--[^\s]+\s*/g, '$1')
327
+ }
328
+ }
320
329
  }
321
330
  return renderDOMElement(root, data, config)
322
331
  }
323
332
 
333
+ export function renderHTMLContent(template: string, data?: Datascopes, config?: FEAASCustomizations, fakeDOM = false) {
334
+ const newTemplate = config?.processTemplate?.(null, template, data) || template
335
+ if (typeof document === 'undefined' || fakeDOM) {
336
+ const { parseHTML } = require('linkedom')
337
+ const { document } = parseHTML(newTemplate)
338
+ return renderDOMElement(document, data, config).toString()
339
+ } else {
340
+ const root = document.createElement('div')
341
+ root.innerHTML = newTemplate
342
+ renderDOMElement(root, data, config)
343
+ return root.innerHTML
344
+ }
345
+ }
346
+
324
347
  export function renderStylesheet(props: CloudStylesheet, style?: HTMLStyleElement) {
325
348
  renderStylesheetPromise(props, (style ||= document.createElement('style')))
326
349
  return style
@@ -344,7 +367,7 @@ export async function renderComponentPromise(props: FEAASComponentProps, root?:
344
367
  if ('template' in props) {
345
368
  return renderDOMContent(root, props.template, props.data, props)
346
369
  } else {
347
- return fetchComponent(props, (template) => {
370
+ return fetchAndRevalidateComponent(props, (template) => {
348
371
  return renderDOMContent(root, template, props.data, props)
349
372
  }).then(() => root)
350
373
  }
package/src/node.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { parseHTML } from 'linkedom'
2
+ import { Datascopes, FEAASCustomizations, renderDOMContent, renderDOMElement } from './dom.js'
3
+
4
+ export * from './basic.js'
5
+
6
+ export function renderHTMLContent(template: string, data?: Datascopes, config?: FEAASCustomizations) {
7
+ const newTemplate = config?.processTemplate?.(null, template, data) || template
8
+ const { document } = parseHTML(newTemplate)
9
+ return renderDOMElement(document, data, config).toString()
10
+ }
package/src/ui/node.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './index.js'
2
+ export { renderHTMLContent } from '../node.js'