lupine.web 1.1.3 → 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 -77
  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
package/src/lib/cookie.ts CHANGED
@@ -1,44 +1,44 @@
1
- export const setCookie = (
2
- name: string,
3
- value: string,
4
- expireDays = 365,
5
- path?: string,
6
- domain?: string,
7
- secure?: string
8
- ) => {
9
- const expires = new Date(new Date().getTime() + expireDays * 24 * 3600000);
10
- document.cookie =
11
- name +
12
- '=' +
13
- escape(value) +
14
- ';expires=' +
15
- expires.toUTCString() +
16
- ';path=' +
17
- (path ? path : '/') +
18
- (domain ? ';domain=' + domain : '') +
19
- (secure ? ';secure' : '');
20
- };
21
-
22
- export const getCookie = (key: string) => {
23
- const cookies = document.cookie.split(';');
24
- for (let i = 0; i < cookies.length; i++) {
25
- const c = cookies[i].trim();
26
- if (c.substring(0, key.length + 1) == key + '=') {
27
- return unescape(c.substring(key.length + 1));
28
- }
29
- }
30
- return null;
31
- };
32
-
33
- export const clearCookie = (name: string, path?: string, domain?: string, secure?: string) => {
34
- document.cookie =
35
- name +
36
- '=;expires=Fri, 02-Jan-1970 00:00:00 GMT' +
37
- ';path=' +
38
- (path ? path : '/') +
39
- (domain ? ';domain=' + domain : '') +
40
- (secure ? ';secure' : '');
41
- };
42
-
43
- // convinent but not good for tree-shaking
44
- export const cookie = { set: setCookie, get: getCookie, clear: clearCookie };
1
+ export const setCookie = (
2
+ name: string,
3
+ value: string,
4
+ expireDays = 365,
5
+ path?: string,
6
+ domain?: string,
7
+ secure?: string
8
+ ) => {
9
+ const expires = new Date(new Date().getTime() + expireDays * 24 * 3600000);
10
+ document.cookie =
11
+ name +
12
+ '=' +
13
+ escape(value) +
14
+ ';expires=' +
15
+ expires.toUTCString() +
16
+ ';path=' +
17
+ (path ? path : '/') +
18
+ (domain ? ';domain=' + domain : '') +
19
+ (secure ? ';secure' : '');
20
+ };
21
+
22
+ export const getCookie = (key: string) => {
23
+ const cookies = document.cookie.split(';');
24
+ for (let i = 0; i < cookies.length; i++) {
25
+ const c = cookies[i].trim();
26
+ if (c.substring(0, key.length + 1) == key + '=') {
27
+ return unescape(c.substring(key.length + 1));
28
+ }
29
+ }
30
+ return null;
31
+ };
32
+
33
+ export const clearCookie = (name: string, path?: string, domain?: string, secure?: string) => {
34
+ document.cookie =
35
+ name +
36
+ '=;expires=Fri, 02-Jan-1970 00:00:00 GMT' +
37
+ ';path=' +
38
+ (path ? path : '/') +
39
+ (domain ? ';domain=' + domain : '') +
40
+ (secure ? ';secure' : '');
41
+ };
42
+
43
+ // convinent but not good for tree-shaking
44
+ export const cookie = { set: setCookie, get: getCookie, clear: clearCookie };
@@ -1,32 +1,32 @@
1
- let flag = 0;
2
- export const debugWatch = (port: number) => {
3
- console.log('Creating debug-watch socket');
4
- const protocol = location.protocol === "https:" ? "wss:" : "ws:";
5
- const socket = new WebSocket(`${protocol}//${location.host}/debug/client`);
6
- window.addEventListener('beforeunload', () => {
7
- socket.close();
8
- });
9
- socket.onopen = () => {
10
- // console.log('Socket open.');
11
- socket.send(JSON.stringify({ message: 'get-flag' }));
12
- };
13
- socket.onmessage = (message) => {
14
- try {
15
- const jsonData = JSON.parse(message.data);
16
- console.log('Debug socket message:', jsonData);
17
- if (jsonData && jsonData.flag) {
18
- if (!flag) {
19
- flag = jsonData.flag;
20
- } else if (flag !== jsonData.flag) {
21
- document.location.reload();
22
- }
23
- }
24
- } catch {}
25
- };
26
- socket.onclose = () => {
27
- console.log('Debug socket close.');
28
- setTimeout(() => {
29
- debugWatch(port);
30
- }, 3000);
31
- };
32
- };
1
+ let flag = 0;
2
+ export const debugWatch = (port: number) => {
3
+ console.log('Creating debug-watch socket');
4
+ const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
5
+ const socket = new WebSocket(`${protocol}//${location.host}/debug/client`);
6
+ window.addEventListener('beforeunload', () => {
7
+ socket.close();
8
+ });
9
+ socket.onopen = () => {
10
+ // console.log('Socket open.');
11
+ socket.send(JSON.stringify({ message: 'get-flag' }));
12
+ };
13
+ socket.onmessage = (message) => {
14
+ try {
15
+ const jsonData = JSON.parse(message.data);
16
+ console.log('Debug socket message:', jsonData);
17
+ if (jsonData && jsonData.flag) {
18
+ if (!flag) {
19
+ flag = jsonData.flag;
20
+ } else if (flag !== jsonData.flag) {
21
+ document.location.reload();
22
+ }
23
+ }
24
+ } catch {}
25
+ };
26
+ socket.onclose = () => {
27
+ console.log('Debug socket close.');
28
+ setTimeout(() => {
29
+ debugWatch(port);
30
+ }, 3000);
31
+ };
32
+ };
package/src/lib/index.ts CHANGED
@@ -1,7 +1,7 @@
1
- export * from './cookie';
2
- export * from './debug-watch';
3
- export * from './is-frontend';
4
- export * from './logger';
5
- export * from './unique-id';
6
- export * from './web-config';
7
- export * from './web-env';
1
+ export * from './cookie';
2
+ export * from './debug-watch';
3
+ export * from './is-frontend';
4
+ export * from './logger';
5
+ export * from './unique-id';
6
+ export * from './web-config';
7
+ export * from './web-env';
@@ -1,3 +1,3 @@
1
- export const isFrontEnd = () => {
2
- return typeof window === 'object' && typeof document === 'object';
3
- };
1
+ export const isFrontEnd = () => {
2
+ return typeof window === 'object' && typeof document === 'object';
3
+ };
package/src/lib/logger.ts CHANGED
@@ -1,55 +1,55 @@
1
- // Colors for console
2
- export const ConsoleColors = {
3
- Red: '#f44336',
4
- Pink: '#e81e63',
5
- Purple: '#9c27b0',
6
- DeepPurple: '#673ab7',
7
- Indigo: '#3f51b5',
8
- Blue: '#2196f3',
9
- LightBlue: '#03a9f4',
10
- Cyan: '#00bcd4',
11
- Teal: '#009688',
12
- Green: '#4caf50',
13
- LightGreen: '#8bc34a',
14
- Lime: '#cddc39',
15
- DarkYellow: '#bfa40e',
16
- Amber: '#ffc107',
17
- Orange: '#ff9800',
18
- DeepOrange: '#ff5722',
19
- Silver: '#c0c0c0',
20
- Gray: '#808080',
21
- Black: '#000000',
22
- };
23
-
24
- export class Logger {
25
- private static enabled = true;
26
- private namespace = '';
27
- private color = '';
28
- constructor(namespace: string, color?: string) {
29
- this.namespace = namespace ? `[${namespace}] ` : '';
30
- if (color) {
31
- this.color = 'color:' + color;
32
- }
33
- }
34
-
35
- static setEnabled(enabled: boolean) {
36
- enabled && !Logger.enabled && console.log(`Logger is enabled.`);
37
- Logger.enabled = enabled;
38
- }
39
-
40
- log(message: string, ...data: (string | object | number | undefined)[]) {
41
- Logger.enabled && console.log(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
42
- }
43
-
44
- timestamp(date?: Date) {
45
- return (date || new Date()).toJSON().substring(11, 23);
46
- }
47
-
48
- warn(message: string, ...data: (string | object | number | undefined)[]) {
49
- console.warn(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
50
- }
51
-
52
- error(message: string, ...data: (string | object | number | undefined)[]) {
53
- console.error(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
54
- }
55
- }
1
+ // Colors for console
2
+ export const ConsoleColors = {
3
+ Red: '#f44336',
4
+ Pink: '#e81e63',
5
+ Purple: '#9c27b0',
6
+ DeepPurple: '#673ab7',
7
+ Indigo: '#3f51b5',
8
+ Blue: '#2196f3',
9
+ LightBlue: '#03a9f4',
10
+ Cyan: '#00bcd4',
11
+ Teal: '#009688',
12
+ Green: '#4caf50',
13
+ LightGreen: '#8bc34a',
14
+ Lime: '#cddc39',
15
+ DarkYellow: '#bfa40e',
16
+ Amber: '#ffc107',
17
+ Orange: '#ff9800',
18
+ DeepOrange: '#ff5722',
19
+ Silver: '#c0c0c0',
20
+ Gray: '#808080',
21
+ Black: '#000000',
22
+ };
23
+
24
+ export class Logger {
25
+ private static enabled = true;
26
+ private namespace = '';
27
+ private color = '';
28
+ constructor(namespace: string, color?: string) {
29
+ this.namespace = namespace ? `[${namespace}] ` : '';
30
+ if (color) {
31
+ this.color = 'color:' + color;
32
+ }
33
+ }
34
+
35
+ static setEnabled(enabled: boolean) {
36
+ enabled && !Logger.enabled && console.log(`Logger is enabled.`);
37
+ Logger.enabled = enabled;
38
+ }
39
+
40
+ log(message: string, ...data: (string | object | number | undefined)[]) {
41
+ Logger.enabled && console.log(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
42
+ }
43
+
44
+ timestamp(date?: Date) {
45
+ return (date || new Date()).toJSON().substring(11, 23);
46
+ }
47
+
48
+ warn(message: string, ...data: (string | object | number | undefined)[]) {
49
+ console.warn(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
50
+ }
51
+
52
+ error(message: string, ...data: (string | object | number | undefined)[]) {
53
+ console.error(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
54
+ }
55
+ }
@@ -1,40 +1,40 @@
1
- /**
2
- * Sample:
3
- * const domUniqueId = uniqueIdGenerator('lj');
4
- * const id1 = domUniqueId();
5
- * const id2 = domUniqueId();
6
- * @param preKey
7
- * @returns A function to generate Unique Ids
8
- */
9
- // export function uniqueIdGenerator2(preKey: string) {
10
- // let count = 0;
11
- // let diff = '';
12
- // return function (reset = false): string {
13
- // if (reset) {
14
- // count = 0;
15
- // diff = '';
16
- // }
17
- // if (count > 9999999999999999) {
18
- // count = 0;
19
- // diff = Math.round(new Date().getTime() / 1000).toString(36) + '-';
20
- // }
21
- // count++;
22
- // return `${preKey}${diff}${count.toString(36)}`;
23
- // };
24
- // }
25
-
26
- export function uniqueIdGenerator(preKey: string) {
27
- let count = 0;
28
- const baseTime = Math.round(Date.now() / 1000);
29
- let lastKey = '';
30
- return function (): string {
31
- const key = Math.round(Date.now() / 1000 - baseTime).toString(36);
32
- if (key !== lastKey) {
33
- count = 0;
34
- lastKey = key;
35
- } else {
36
- count++;
37
- }
38
- return `${preKey}${lastKey}${count.toString(36)}`;
39
- };
40
- }
1
+ /**
2
+ * Sample:
3
+ * const domUniqueId = uniqueIdGenerator('lj');
4
+ * const id1 = domUniqueId();
5
+ * const id2 = domUniqueId();
6
+ * @param preKey
7
+ * @returns A function to generate Unique Ids
8
+ */
9
+ // export function uniqueIdGenerator2(preKey: string) {
10
+ // let count = 0;
11
+ // let diff = '';
12
+ // return function (reset = false): string {
13
+ // if (reset) {
14
+ // count = 0;
15
+ // diff = '';
16
+ // }
17
+ // if (count > 9999999999999999) {
18
+ // count = 0;
19
+ // diff = Math.round(new Date().getTime() / 1000).toString(36) + '-';
20
+ // }
21
+ // count++;
22
+ // return `${preKey}${diff}${count.toString(36)}`;
23
+ // };
24
+ // }
25
+
26
+ export function uniqueIdGenerator(preKey: string) {
27
+ let count = 0;
28
+ const baseTime = Math.round(Date.now() / 1000);
29
+ let lastKey = '';
30
+ return function (): string {
31
+ const key = Math.round(Date.now() / 1000 - baseTime).toString(36);
32
+ if (key !== lastKey) {
33
+ count = 0;
34
+ lastKey = key;
35
+ } else {
36
+ count++;
37
+ }
38
+ return `${preKey}${lastKey}${count.toString(36)}`;
39
+ };
40
+ }
@@ -1,77 +1,79 @@
1
- import { getRenderPageProps } from 'lupine.web';
2
-
3
- // for mobile app, it needs the url to fetch the config for the first time
4
- export const bindWebConfigApi = (webConfigApi: string) => {
5
- WebConfig.webConfigApi = webConfigApi;
6
- };
7
-
8
- export class WebConfig {
9
- static webConfigApi = '';
10
- static initialized = false;
11
- static cfg: { [key: string]: string } = {};
12
-
13
- // called from generatePage (SSR)
14
- static initFromData(cfg: { [key: string]: string }) {
15
- this.initialized = true;
16
- this.cfg = cfg;
17
- }
18
-
19
- static async init(force?: boolean) {
20
- if (this.initialized && !force) {
21
- return;
22
- }
23
- this.initialized = true;
24
-
25
- // For web, it's injected in the html by SSR, but for mobile, it's fetched from api
26
- if (typeof document === 'object' && !force) {
27
- const json = document.querySelector('#web-setting')?.textContent;
28
- if (json) {
29
- this.cfg = JSON.parse(json);
30
- return;
31
- }
32
- }
33
-
34
- if (!this.webConfigApi) {
35
- console.error('WebConfig webConfigApi is not set');
36
- return;
37
- }
38
- const url = getRenderPageProps().renderPageFunctions.baseUrl(this.webConfigApi);
39
- const data = await getRenderPageProps().renderPageFunctions.fetchData(url);
40
- if (data && data.json && data.json.status === 'ok') {
41
- this.cfg = data.json.result;
42
- } else {
43
- console.error(data?.json?.message || 'Failed to get web config');
44
- }
45
- }
46
-
47
- static async get(key: string, defaultValue: number): Promise<number>;
48
- static async get(key: string, defaultValue: string): Promise<string>;
49
- static async get(key: string, defaultValue: boolean): Promise<boolean>;
50
- static async get(key: string, defaultValue: object): Promise<object>;
51
- static async get(key: string, defaultValue?: any): Promise<any> {
52
- await WebConfig.init();
53
-
54
- if (typeof WebConfig.cfg[key] === 'undefined') {
55
- return defaultValue;
56
- }
57
-
58
- if (typeof defaultValue === 'number') {
59
- return Number.parseInt(WebConfig.cfg[key]!);
60
- }
61
- if (typeof defaultValue === 'boolean') {
62
- return WebConfig.cfg[key]!.toLocaleLowerCase() === 'true' || WebConfig.cfg[key] === '1';
63
- }
64
- if (typeof defaultValue === 'object') {
65
- if (typeof WebConfig.cfg[key] === 'object') {
66
- return WebConfig.cfg[key];
67
- }
68
- try {
69
- return JSON.parse(WebConfig.cfg[key]!);
70
- } catch (error) {
71
- console.error(`WebConfig JSON.parse error: `, error);
72
- }
73
- return defaultValue;
74
- }
75
- return WebConfig.cfg[key] || defaultValue;
76
- }
77
- }
1
+ import { getRenderPageProps } from 'lupine.web';
2
+
3
+ // for mobile app, it needs the url to fetch the config for the first time
4
+ export const bindWebConfigApi = (webConfigApi: string) => {
5
+ WebConfig.webConfigApi = webConfigApi;
6
+ };
7
+
8
+ export class WebConfig {
9
+ static webConfigApi = '';
10
+ static initialized = false;
11
+ static cfg: { [key: string]: string } = {};
12
+
13
+ // called from generatePage (SSR)
14
+ static initFromData(cfg: { [key: string]: string }) {
15
+ this.initialized = true;
16
+ this.cfg = cfg;
17
+ }
18
+
19
+ static async init(force?: boolean) {
20
+ if (this.initialized && !force) {
21
+ return;
22
+ }
23
+ this.initialized = true;
24
+
25
+ // For web, it's injected in the html by SSR, but for mobile, it's fetched from api
26
+ if (typeof document === 'object' && !force) {
27
+ const json = document.querySelector('#web-setting')?.textContent;
28
+ if (json) {
29
+ this.cfg = JSON.parse(json);
30
+ return;
31
+ }
32
+ }
33
+
34
+ if (!this.webConfigApi) {
35
+ console.error('WebConfig webConfigApi is not set');
36
+ return;
37
+ }
38
+ const url = getRenderPageProps().renderPageFunctions.baseUrl(this.webConfigApi);
39
+ const data = await getRenderPageProps().renderPageFunctions.fetchData(url);
40
+ if (data && data.json && data.json.status === 'ok') {
41
+ this.cfg = data.json.result;
42
+ } else {
43
+ console.error(data?.json?.message || 'Failed to get web config');
44
+ }
45
+ }
46
+
47
+ static async get(key: string, defaultValue: number): Promise<number>;
48
+ static async get(key: string, defaultValue: string): Promise<string>;
49
+ static async get(key: string, defaultValue: boolean): Promise<boolean>;
50
+ static async get(key: string, defaultValue: object): Promise<object>;
51
+ static async get(key: string, defaultValue?: any): Promise<any> {
52
+ await WebConfig.init();
53
+
54
+ const v = WebConfig.cfg[key];
55
+ if (typeof v === 'undefined') {
56
+ return defaultValue;
57
+ }
58
+
59
+ if (typeof defaultValue === 'number') {
60
+ return Number.parseInt(v!);
61
+ }
62
+ if (typeof defaultValue === 'boolean') {
63
+ return v!.toLocaleLowerCase() === 'true' || v === '1';
64
+ }
65
+ if (typeof defaultValue === 'object') {
66
+ if (typeof v === 'object') {
67
+ return v;
68
+ }
69
+ try {
70
+ return JSON.parse(v!);
71
+ } catch (error) {
72
+ console.error(`WebConfig JSON.parse error: `, error);
73
+ }
74
+ return defaultValue;
75
+ }
76
+ // if empty, then return default value
77
+ return v || defaultValue;
78
+ }
79
+ }