lupine.web 1.1.4 → 1.1.5

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 (41) hide show
  1. package/README.md +66 -3
  2. package/jsx-runtime/index.js +14 -14
  3. package/jsx-runtime/package.json +16 -16
  4. package/jsx-runtime/src/index.d.ts +2 -2
  5. package/package.json +53 -52
  6. package/src/core/bind-attributes.ts +61 -61
  7. package/src/core/bind-lang.ts +52 -52
  8. package/src/core/bind-links.ts +26 -16
  9. package/src/core/bind-meta.tsx +52 -52
  10. package/src/core/bind-ref.ts +51 -51
  11. package/src/core/bind-styles.ts +239 -239
  12. package/src/core/bind-theme.ts +53 -53
  13. package/src/core/camel-to-hyphens.ts +3 -3
  14. package/src/core/export-lupine.ts +80 -80
  15. package/src/core/index.ts +17 -17
  16. package/src/core/initialize.ts +116 -116
  17. package/src/core/mount-component.ts +72 -68
  18. package/src/core/page-loaded-events.ts +16 -16
  19. package/src/core/page-router.ts +180 -180
  20. package/src/core/render-component.ts +230 -233
  21. package/src/core/replace-innerhtml.ts +23 -23
  22. package/src/core/server-cookie.ts +24 -24
  23. package/src/global.d.ts +66 -66
  24. package/src/index.ts +14 -14
  25. package/src/jsx.ts +1044 -1043
  26. package/src/lib/cookie.ts +44 -44
  27. package/src/lib/debug-watch.ts +32 -32
  28. package/src/lib/index.ts +7 -7
  29. package/src/lib/is-frontend.ts +3 -3
  30. package/src/lib/logger.ts +55 -55
  31. package/src/lib/unique-id.ts +40 -40
  32. package/src/lib/web-config.ts +79 -79
  33. package/src/lib/web-env.ts +99 -99
  34. package/src/models/index.ts +4 -4
  35. package/src/models/json-props.ts +8 -8
  36. package/src/models/simple-storage-props.ts +9 -9
  37. package/src/models/theme-props.ts +7 -7
  38. package/src/models/to-client-delivery-props.ts +8 -8
  39. package/src/styles/css-styles.ts +814 -814
  40. package/src/styles/index.ts +4 -4
  41. package/tsconfig.json +113 -113
@@ -1,233 +1,230 @@
1
- import { Logger } from '../lib/logger';
2
- import { uniqueIdGenerator } from '../lib/unique-id';
3
- import { processStyle } from './bind-styles';
4
- // import { bindPageResetEvent } from './page-reset-events';
5
- import { camelToHyphens } from './camel-to-hyphens';
6
-
7
- const logger = new Logger('render-components');
8
- export const domUniqueId = uniqueIdGenerator('l'); // l means label
9
- // bindPageResetEvent(() => {
10
- // // reset unique id
11
- // domUniqueId(true);
12
- // });
13
-
14
- function renderChildren(html: string[], children: any, uniqueClassName?: string, globalCssId?: string) {
15
- if (typeof children === 'string') {
16
- html.push(children);
17
- } else if (children === false || children === null || typeof children === 'undefined') {
18
- // add nothing
19
- } else if (typeof children === 'number' || typeof children === 'boolean') {
20
- // true will be added
21
- html.push(children.toString());
22
- } else if (Array.isArray(children)) {
23
- for (let i = 0; i < children.length; i++) {
24
- const item = children[i];
25
- renderChildren(html, item, uniqueClassName, globalCssId);
26
- }
27
- } else if (children.type && children.props) {
28
- renderComponent(children.type, children.props, uniqueClassName, globalCssId);
29
- html.push(...children.props._html);
30
- children.props._html.length = 0;
31
- } else {
32
- logger.warn('Unexpected', children);
33
- }
34
- }
35
-
36
- const selfClosingTags = [
37
- 'area',
38
- 'base',
39
- 'br',
40
- 'col',
41
- 'embed',
42
- 'hr',
43
- 'img',
44
- 'input',
45
- 'link',
46
- 'meta',
47
- 'param',
48
- 'source',
49
- 'track',
50
- 'wbr',
51
- ];
52
-
53
- const genUniqueId = (props: any) => {
54
- if (!props._id) {
55
- props._id = domUniqueId();
56
- }
57
- return props._id;
58
- };
59
- // data-refid will be assigned with a ref.id
60
- function renderAttribute(type: any, props: any, jsxNodes: any, uniqueClassName?: string, globalCssId?: string) {
61
- const html = [];
62
- // data-refid is used for nested components like this:
63
- // <div class='class-name' ref={ref} ...>...
64
- // <div data-refid={ref}>
65
- // then data-refid can be located:
66
- // ref.$(`.class-name[data-refid=${ref.id}]`)
67
- // if (props['data-refid'] && props['data-refid'].id) {
68
- // props['data-refid'] = props['data-refid'].id;
69
- // }
70
- for (let i in props) {
71
- if (i === 'ref') {
72
- if (props[i]) {
73
- props[i].id = genUniqueId(props);
74
- html.push('data-ref');
75
- }
76
- } else if (!['children', 'key', '_result', '_html', '_id'].includes(i)) {
77
- //, "_lb"
78
- // , "value", "checked"
79
- // style is a string, in-line style
80
- if (i === 'style') {
81
- if (typeof props[i] === 'object') {
82
- let attrs = `${i}="`;
83
- for (let j in props[i]) {
84
- attrs += `${camelToHyphens(j)}:${props[i][j]};`;
85
- }
86
- attrs += `"`;
87
- html.push(attrs);
88
- } else {
89
- html.push(`${i}="${props[i]}"`);
90
- }
91
- } else if (i === 'css') {
92
- // css is a <style> tag, and is the first element in html
93
- genUniqueId(props);
94
- // props._lb = props._id;
95
- } else if (i[0] === 'o' && i[1] === 'n') {
96
- genUniqueId(props);
97
- } else if (i === 'defaultChecked') {
98
- if (props[i] === true || props[i] === 'checked') {
99
- html.push(`checked="true"`);
100
- }
101
- } else if (i === 'readonly' || i === 'disabled' || i === 'selected' || i === 'checked') {
102
- if (props[i] !== undefined && props[i] !== false && props[i] !== 'false') {
103
- html.push(`${i}="${props[i]}"`);
104
- }
105
- } else if (i === 'class' || i === 'className') {
106
- let classNameList = props[i].split(' ').filter((item: string) => item && item !== '');
107
- if ((props['css'] || props['ref']) && !classNameList.includes(props._id)) {
108
- // add as the first
109
- classNameList.unshift(props._id);
110
- }
111
- if (props['ref'] && props['ref'].globalCssId && !classNameList.includes(props['ref'].globalCssId)) {
112
- // add as the first
113
- classNameList.unshift(props['ref'].globalCssId);
114
- }
115
- if (globalCssId && uniqueClassName) {
116
- // &xx -> globalCssId + xx and uniqueClassName+xx
117
- classNameList = classNameList.flatMap((item: string) => {
118
- if (item.includes('&')) {
119
- return [item.replace(/&/g, globalCssId), item.replace(/&/g, uniqueClassName)];
120
- }
121
- return [item];
122
- });
123
- } else if (globalCssId) {
124
- classNameList = classNameList.map((item: string) => item.replace(/&/g, globalCssId));
125
- } else if (uniqueClassName) {
126
- classNameList = classNameList.map((item: string) => item.replace(/&/g, uniqueClassName));
127
- }
128
- html.push(`class="${classNameList.join(' ')}"`);
129
- } else if (i !== 'dangerouslySetInnerHTML') {
130
- html.push(`${i}="${props[i]}"`);
131
- }
132
- }
133
- }
134
- if (props._id) {
135
- // tag id will be after all attributes
136
- html.push(props._id);
137
- }
138
- return html.join(' ');
139
- }
140
-
141
- // The result has only one element
142
- export const renderComponent = (type: any, props: any, uniqueClassName?: string, globalCssId?: string) => {
143
- // logger.log("==================renderComponent", type);
144
- if (Array.isArray(props)) {
145
- const jsxNodes = { type: 'Fragment', props: { children: props } } as any;
146
- renderComponent(jsxNodes.type, jsxNodes.props, uniqueClassName, globalCssId);
147
- return;
148
- }
149
-
150
- props._html = [];
151
- if (typeof type === 'function') {
152
- props._result = type.call(null, props);
153
- if (props._result === null || props._result === undefined || props._result === false) {
154
- // placeholder for sub components
155
- props._result = { type: 'Fragment', props };
156
- }
157
- // if (props._fragment_ref && props._result && props._result.props) {
158
- // // pass the ref to the sub Fragment tag
159
- // props._result.props.ref = props._fragment_ref;
160
- // props._result.props._id = genUniqueId(props._result.props);
161
- // }
162
- // logger.log('==========props._result', props._result);
163
- if (typeof props._result.type === 'function') {
164
- renderComponent(props._result.type, props._result.props, uniqueClassName, globalCssId);
165
- if (props._result.props._html) {
166
- props._html.push(...props._result.props._html);
167
- props._result.props._html.length = 0;
168
- }
169
- // function component doesn't have any attributes
170
- return;
171
- }
172
- }
173
- const newType = (props._result && props._result.type) || type;
174
- const newProps = (props._result && props._result.props) || props;
175
- if (newType === 'div' && newProps.class === 'answer-box') {
176
- console.log('renderComponent', newType, newProps);
177
- }
178
- if (typeof newType === 'string') {
179
- if (newProps._id) {
180
- console.warn('This component reference is used more than once and will have binding issues: ', newProps);
181
- }
182
- let newUniqueClassName = uniqueClassName;
183
- if (newProps['css'] || newProps['ref']) {
184
- newUniqueClassName = genUniqueId(newProps);
185
- if (!newProps['class'] && !newProps['className']) {
186
- newProps['class'] = newUniqueClassName;
187
- }
188
- }
189
- let newGlobalCssId = globalCssId;
190
- if (newProps['ref'] && newProps['ref'].globalCssId) {
191
- newGlobalCssId = newProps['ref'].globalCssId;
192
- }
193
- const attrs = renderAttribute(newType, newProps, { type, props }, newUniqueClassName, newGlobalCssId);
194
- if (selfClosingTags.includes(newType.toLowerCase())) {
195
- // for Fragment, only needs this tag when Ref is assigned
196
- if (newType !== 'Fragment' || newProps.ref) {
197
- props._html.push(`<${newType}${attrs ? ' ' : ''}${attrs} />`);
198
- }
199
- if (newProps['css']) {
200
- console.warn(`ClosingTag [${newType}] doesn't support 'css', please use 'style' instead.`);
201
- }
202
- } else {
203
- if (newType !== 'Fragment' || newProps.ref) {
204
- props._html.push(`<${newType}${attrs ? ' ' : ''}${attrs}>`);
205
- }
206
-
207
- if (newProps['css']) {
208
- const cssText = processStyle(newUniqueClassName!, newProps['css']).join('');
209
- props._html.push(`<style id="sty-${newUniqueClassName}">${cssText}</style>`); // sty means style, and updateStyles has the same name
210
- }
211
-
212
- if (newProps.children || newProps.children === 0) {
213
- // if (newProps._lb) {
214
- // assignLabels(newProps._lb, newProps.children);
215
- // }
216
-
217
- renderChildren(props._html, newProps.children, newUniqueClassName, newGlobalCssId);
218
- } else if (newProps['dangerouslySetInnerHTML']) {
219
- props._html.push(newProps['dangerouslySetInnerHTML']);
220
- } else {
221
- // single element
222
- }
223
-
224
- if (newType !== 'Fragment' || newProps.ref) {
225
- props._html.push(`</${newType}>`);
226
- }
227
- }
228
- } else if (newType.name === 'Fragment') {
229
- renderChildren(props._html, newProps.children, uniqueClassName, globalCssId);
230
- } else {
231
- logger.warn('Unknown type: ', type, props, newType, newProps);
232
- }
233
- };
1
+ import { Logger } from '../lib/logger';
2
+ import { uniqueIdGenerator } from '../lib/unique-id';
3
+ import { processStyle } from './bind-styles';
4
+ // import { bindPageResetEvent } from './page-reset-events';
5
+ import { camelToHyphens } from './camel-to-hyphens';
6
+
7
+ const logger = new Logger('render-components');
8
+ export const domUniqueId = uniqueIdGenerator('l'); // l means label
9
+ // bindPageResetEvent(() => {
10
+ // // reset unique id
11
+ // domUniqueId(true);
12
+ // });
13
+
14
+ function renderChildren(html: string[], children: any, uniqueClassName?: string, globalCssId?: string) {
15
+ if (typeof children === 'string') {
16
+ html.push(children);
17
+ } else if (children === false || children === null || typeof children === 'undefined') {
18
+ // add nothing
19
+ } else if (typeof children === 'number' || typeof children === 'boolean') {
20
+ // true will be added
21
+ html.push(children.toString());
22
+ } else if (Array.isArray(children)) {
23
+ for (let i = 0; i < children.length; i++) {
24
+ const item = children[i];
25
+ renderChildren(html, item, uniqueClassName, globalCssId);
26
+ }
27
+ } else if (children.type && children.props) {
28
+ renderComponent(children.type, children.props, uniqueClassName, globalCssId);
29
+ html.push(...children.props._html);
30
+ children.props._html.length = 0;
31
+ } else {
32
+ logger.warn('Unexpected', children);
33
+ }
34
+ }
35
+
36
+ const selfClosingTags = [
37
+ 'area',
38
+ 'base',
39
+ 'br',
40
+ 'col',
41
+ 'embed',
42
+ 'hr',
43
+ 'img',
44
+ 'input',
45
+ 'link',
46
+ 'meta',
47
+ 'param',
48
+ 'source',
49
+ 'track',
50
+ 'wbr',
51
+ ];
52
+
53
+ const genUniqueId = (props: any) => {
54
+ if (!props._id) {
55
+ props._id = domUniqueId();
56
+ }
57
+ return props._id;
58
+ };
59
+ // data-refid will be assigned with a ref.id
60
+ function renderAttribute(type: any, props: any, jsxNodes: any, uniqueClassName?: string, globalCssId?: string) {
61
+ const html = [];
62
+ // data-refid is used for nested components like this:
63
+ // <div class='class-name' ref={ref} ...>...
64
+ // <div data-refid={ref}>
65
+ // then data-refid can be located:
66
+ // ref.$(`.class-name[data-refid=${ref.id}]`)
67
+ // if (props['data-refid'] && props['data-refid'].id) {
68
+ // props['data-refid'] = props['data-refid'].id;
69
+ // }
70
+ for (let i in props) {
71
+ if (i === 'ref') {
72
+ if (props[i]) {
73
+ props[i].id = genUniqueId(props);
74
+ html.push('data-ref');
75
+ }
76
+ } else if (!['children', 'key', '_result', '_html', '_id'].includes(i)) {
77
+ //, "_lb"
78
+ // , "value", "checked"
79
+ // style is a string, in-line style
80
+ if (i === 'style') {
81
+ if (typeof props[i] === 'object') {
82
+ let attrs = `${i}="`;
83
+ for (let j in props[i]) {
84
+ attrs += `${camelToHyphens(j)}:${props[i][j]};`;
85
+ }
86
+ attrs += `"`;
87
+ html.push(attrs);
88
+ } else {
89
+ html.push(`${i}="${props[i]}"`);
90
+ }
91
+ } else if (i === 'css') {
92
+ // css is a <style> tag, and is the first element in html
93
+ genUniqueId(props);
94
+ // props._lb = props._id;
95
+ } else if (i[0] === 'o' && i[1] === 'n') {
96
+ genUniqueId(props);
97
+ } else if (i === 'defaultChecked') {
98
+ if (props[i] === true || props[i] === 'checked') {
99
+ html.push(`checked="true"`);
100
+ }
101
+ } else if (i === 'readonly' || i === 'disabled' || i === 'selected' || i === 'checked') {
102
+ if (props[i] !== undefined && props[i] !== false && props[i] !== 'false') {
103
+ html.push(`${i}="${props[i]}"`);
104
+ }
105
+ } else if (i === 'class' || i === 'className') {
106
+ let classNameList = props[i].split(' ').filter((item: string) => item && item !== '');
107
+ if ((props['css'] || props['ref']) && !classNameList.includes(props._id)) {
108
+ // add as the first
109
+ classNameList.unshift(props._id);
110
+ }
111
+ if (props['ref'] && props['ref'].globalCssId && !classNameList.includes(props['ref'].globalCssId)) {
112
+ // add as the first
113
+ classNameList.unshift(props['ref'].globalCssId);
114
+ }
115
+ if (globalCssId && uniqueClassName) {
116
+ // &xx -> globalCssId + xx and uniqueClassName+xx
117
+ classNameList = classNameList.flatMap((item: string) => {
118
+ if (item.includes('&')) {
119
+ return [item.replace(/&/g, globalCssId), item.replace(/&/g, uniqueClassName)];
120
+ }
121
+ return [item];
122
+ });
123
+ } else if (globalCssId) {
124
+ classNameList = classNameList.map((item: string) => item.replace(/&/g, globalCssId));
125
+ } else if (uniqueClassName) {
126
+ classNameList = classNameList.map((item: string) => item.replace(/&/g, uniqueClassName));
127
+ }
128
+ html.push(`class="${classNameList.join(' ')}"`);
129
+ } else if (i !== 'dangerouslySetInnerHTML') {
130
+ html.push(`${i}="${props[i]}"`);
131
+ }
132
+ }
133
+ }
134
+ if (props._id) {
135
+ // tag id will be after all attributes
136
+ html.push(props._id);
137
+ }
138
+ return html.join(' ');
139
+ }
140
+
141
+ // The result has only one element
142
+ export const renderComponent = (type: any, props: any, uniqueClassName?: string, globalCssId?: string) => {
143
+ // logger.log("==================renderComponent", type);
144
+ if (Array.isArray(props)) {
145
+ const jsxNodes = { type: 'Fragment', props: { children: props } } as any;
146
+ renderComponent(jsxNodes.type, jsxNodes.props, uniqueClassName, globalCssId);
147
+ return;
148
+ }
149
+
150
+ props._html = [];
151
+ if (typeof type === 'function') {
152
+ props._result = type.call(null, props);
153
+ if (props._result === null || props._result === undefined || props._result === false) {
154
+ // placeholder for sub components
155
+ props._result = { type: 'Fragment', props };
156
+ }
157
+ // if (props._fragment_ref && props._result && props._result.props) {
158
+ // // pass the ref to the sub Fragment tag
159
+ // props._result.props.ref = props._fragment_ref;
160
+ // props._result.props._id = genUniqueId(props._result.props);
161
+ // }
162
+ // logger.log('==========props._result', props._result);
163
+ if (typeof props._result.type === 'function') {
164
+ renderComponent(props._result.type, props._result.props, uniqueClassName, globalCssId);
165
+ if (props._result.props._html) {
166
+ props._html.push(...props._result.props._html);
167
+ props._result.props._html.length = 0;
168
+ }
169
+ // function component doesn't have any attributes
170
+ return;
171
+ }
172
+ }
173
+ const newType = (props._result && props._result.type) || type;
174
+ const newProps = (props._result && props._result.props) || props;
175
+ if (typeof newType === 'string') {
176
+ if (newProps._id) {
177
+ console.warn('This component reference is used more than once and will have binding issues: ', newProps);
178
+ }
179
+ let newUniqueClassName = uniqueClassName;
180
+ if (newProps['css'] || newProps['ref']) {
181
+ newUniqueClassName = genUniqueId(newProps);
182
+ if (!newProps['class'] && !newProps['className']) {
183
+ newProps['class'] = newUniqueClassName;
184
+ }
185
+ }
186
+ let newGlobalCssId = globalCssId;
187
+ if (newProps['ref'] && newProps['ref'].globalCssId) {
188
+ newGlobalCssId = newProps['ref'].globalCssId;
189
+ }
190
+ const attrs = renderAttribute(newType, newProps, { type, props }, newUniqueClassName, newGlobalCssId);
191
+ if (selfClosingTags.includes(newType.toLowerCase())) {
192
+ // for Fragment, only needs this tag when Ref is assigned
193
+ if (newType !== 'Fragment' || newProps.ref) {
194
+ props._html.push(`<${newType}${attrs ? ' ' : ''}${attrs} />`);
195
+ }
196
+ if (newProps['css']) {
197
+ console.warn(`ClosingTag [${newType}] doesn't support 'css', please use 'style' instead.`);
198
+ }
199
+ } else {
200
+ if (newType !== 'Fragment' || newProps.ref) {
201
+ props._html.push(`<${newType}${attrs ? ' ' : ''}${attrs}>`);
202
+ }
203
+
204
+ if (newProps['css']) {
205
+ const cssText = processStyle(newUniqueClassName!, newProps['css']).join('');
206
+ props._html.push(`<style id="sty-${newUniqueClassName}">${cssText}</style>`); // sty means style, and updateStyles has the same name
207
+ }
208
+
209
+ if (newProps.children || newProps.children === 0) {
210
+ // if (newProps._lb) {
211
+ // assignLabels(newProps._lb, newProps.children);
212
+ // }
213
+
214
+ renderChildren(props._html, newProps.children, newUniqueClassName, newGlobalCssId);
215
+ } else if (newProps['dangerouslySetInnerHTML']) {
216
+ props._html.push(newProps['dangerouslySetInnerHTML']);
217
+ } else {
218
+ // single element
219
+ }
220
+
221
+ if (newType !== 'Fragment' || newProps.ref) {
222
+ props._html.push(`</${newType}>`);
223
+ }
224
+ }
225
+ } else if (newType.name === 'Fragment') {
226
+ renderChildren(props._html, newProps.children, uniqueClassName, globalCssId);
227
+ } else {
228
+ logger.warn('Unknown type: ', type, props, newType, newProps);
229
+ }
230
+ };
@@ -1,23 +1,23 @@
1
- export const replaceInnerhtml = async (el: Element, newHtml: string) => {
2
- // keep <style id="sty-${newProps._id}">...</style>
3
- const firstDom = el.firstChild as Element;
4
- if (firstDom && firstDom.tagName === 'STYLE') {
5
- firstDom.parentNode?.removeChild(firstDom);
6
- }
7
-
8
- await callUnload(el);
9
- el.innerHTML = newHtml;
10
-
11
- if (firstDom && firstDom.tagName === 'STYLE') {
12
- el.insertBefore(firstDom, el.firstChild);
13
- }
14
- };
15
- export const callUnload = async (el: Element) => {
16
- const promises: Promise<void>[] = [];
17
- el.querySelectorAll('[data-ref]').forEach((child: any) => {
18
- if (child._lj && child._lj.onUnload) {
19
- promises.push(child._lj.onUnload());
20
- }
21
- });
22
- await Promise.all(promises);
23
- };
1
+ export const replaceInnerhtml = async (el: Element, newHtml: string) => {
2
+ // keep <style id="sty-${newProps._id}">...</style>
3
+ const firstDom = el.firstChild as Element;
4
+ if (firstDom && firstDom.tagName === 'STYLE') {
5
+ firstDom.parentNode?.removeChild(firstDom);
6
+ }
7
+
8
+ await callUnload(el);
9
+ el.innerHTML = newHtml;
10
+
11
+ if (firstDom && firstDom.tagName === 'STYLE') {
12
+ el.insertBefore(firstDom, el.firstChild);
13
+ }
14
+ };
15
+ export const callUnload = async (el: Element) => {
16
+ const promises: Promise<void>[] = [];
17
+ el.querySelectorAll('[data-ref]').forEach((child: any) => {
18
+ if (child._lj && child._lj.onUnload) {
19
+ promises.push(child._lj.onUnload());
20
+ }
21
+ });
22
+ await Promise.all(promises);
23
+ };
@@ -1,24 +1,24 @@
1
- import { getCookie } from '../lib/cookie';
2
- import { ISimpleStorage } from '../models/simple-storage-props';
3
- import { isFrontEnd } from '../lib/is-frontend';
4
-
5
- // getEitherCookie can be used in both FE and SSR
6
- export const getEitherCookie = (name: string) => {
7
- if (!isFrontEnd()) {
8
- // SSR
9
- return getServerCookie(name);
10
- } else {
11
- return getCookie(name);
12
- }
13
- };
14
-
15
- // In SSR (server-side-rendering), some components may need to access cookies
16
- let _serverCookies: ISimpleStorage;
17
- export const getServerCookie = (name: string) => {
18
- return _serverCookies && _serverCookies.get(name, '');
19
- };
20
- // TODO: Server cookies safety should be OK? as this is dropped after SSR
21
- // This is called by server side to initialize cookies for SSR
22
- export const initServerCookies = (serverCookies: ISimpleStorage) => {
23
- return (_serverCookies = serverCookies);
24
- };
1
+ import { getCookie } from '../lib/cookie';
2
+ import { ISimpleStorage } from '../models/simple-storage-props';
3
+ import { isFrontEnd } from '../lib/is-frontend';
4
+
5
+ // getEitherCookie can be used in both FE and SSR
6
+ export const getEitherCookie = (name: string) => {
7
+ if (!isFrontEnd()) {
8
+ // SSR
9
+ return getServerCookie(name);
10
+ } else {
11
+ return getCookie(name);
12
+ }
13
+ };
14
+
15
+ // In SSR (server-side-rendering), some components may need to access cookies
16
+ let _serverCookies: ISimpleStorage;
17
+ export const getServerCookie = (name: string) => {
18
+ return _serverCookies && _serverCookies.get(name, '');
19
+ };
20
+ // TODO: Server cookies safety should be OK? as this is dropped after SSR
21
+ // This is called by server side to initialize cookies for SSR
22
+ export const initServerCookies = (serverCookies: ISimpleStorage) => {
23
+ return (_serverCookies = serverCookies);
24
+ };