valyrian.js 7.2.11 → 8.0.0
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.
- package/README.md +6 -6
- package/dist/flux-store/index.d.ts +32 -0
- package/dist/flux-store/index.d.ts.map +1 -0
- package/dist/flux-store/index.js +258 -0
- package/dist/flux-store/index.js.map +7 -0
- package/dist/flux-store/index.min.js +1 -0
- package/dist/flux-store/index.min.js.map +1 -0
- package/dist/flux-store/index.mjs +237 -0
- package/dist/flux-store/index.mjs.map +7 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +42 -75
- package/dist/hooks/index.js.map +2 -2
- package/dist/hooks/index.min.js +1 -0
- package/dist/hooks/index.min.js.map +1 -0
- package/dist/hooks/index.mjs +43 -76
- package/dist/hooks/index.mjs.map +2 -2
- package/dist/index.d.ts +52 -54
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +397 -328
- package/dist/index.js.map +3 -3
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +397 -328
- package/dist/index.mjs.map +3 -3
- package/dist/native-store/index.d.ts +14 -0
- package/dist/native-store/index.d.ts.map +1 -0
- package/dist/native-store/index.js +103 -0
- package/dist/native-store/index.js.map +7 -0
- package/dist/native-store/index.min.js +1 -0
- package/dist/native-store/index.min.js.map +1 -0
- package/dist/native-store/index.mjs +82 -0
- package/dist/native-store/index.mjs.map +7 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +223 -86
- package/dist/node/index.js.map +4 -4
- package/dist/node/index.mjs +223 -86
- package/dist/node/index.mjs.map +4 -4
- package/dist/node/node.sw.js +152 -0
- package/dist/node/utils/inline.d.ts.map +1 -1
- package/dist/node/utils/node.sw.js +152 -0
- package/dist/node/utils/session-storage.d.ts +22 -0
- package/dist/node/utils/session-storage.d.ts.map +1 -0
- package/dist/node/utils/sw.d.ts.map +1 -1
- package/dist/node/utils/tree-adapter.d.ts +9 -0
- package/dist/node/utils/tree-adapter.d.ts.map +1 -1
- package/dist/pulse-store/index.d.ts +13 -0
- package/dist/pulse-store/index.d.ts.map +1 -0
- package/dist/pulse-store/index.js +143 -0
- package/dist/pulse-store/index.js.map +7 -0
- package/dist/pulse-store/index.min.js +1 -0
- package/dist/pulse-store/index.min.js.map +1 -0
- package/dist/pulse-store/index.mjs +122 -0
- package/dist/pulse-store/index.mjs.map +7 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +68 -89
- package/dist/request/index.js.map +2 -2
- package/dist/request/index.min.js +1 -0
- package/dist/request/index.min.js.map +1 -0
- package/dist/request/index.mjs +68 -89
- package/dist/request/index.mjs.map +2 -2
- package/dist/router/index.d.ts +32 -31
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +256 -104
- package/dist/router/index.js.map +3 -3
- package/dist/router/index.min.js +1 -0
- package/dist/router/index.min.js.map +1 -0
- package/dist/router/index.mjs +256 -104
- package/dist/router/index.mjs.map +3 -3
- package/dist/signals/index.d.ts +6 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/index.js +92 -0
- package/dist/signals/index.js.map +7 -0
- package/dist/signals/index.min.js +1 -0
- package/dist/signals/index.min.js.map +1 -0
- package/dist/signals/index.mjs +71 -0
- package/dist/signals/index.mjs.map +7 -0
- package/dist/suspense/index.d.ts +6 -0
- package/dist/suspense/index.d.ts.map +1 -0
- package/dist/suspense/index.js +67 -0
- package/dist/suspense/index.js.map +7 -0
- package/dist/suspense/index.min.js +1 -0
- package/dist/suspense/index.min.js.map +1 -0
- package/dist/suspense/index.mjs +46 -0
- package/dist/suspense/index.mjs.map +7 -0
- package/dist/sw/index.min.js +1 -0
- package/dist/sw/index.min.js.map +1 -0
- package/dist/translate/index.d.ts +19 -0
- package/dist/translate/index.d.ts.map +1 -0
- package/dist/translate/index.js +150 -0
- package/dist/translate/index.js.map +7 -0
- package/dist/translate/index.min.js +1 -0
- package/dist/translate/index.min.js.map +1 -0
- package/dist/translate/index.mjs +129 -0
- package/dist/translate/index.mjs.map +7 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/deep-freeze.d.ts +3 -0
- package/dist/utils/deep-freeze.d.ts.map +1 -0
- package/dist/utils/getter-setter.d.ts +3 -0
- package/dist/utils/getter-setter.d.ts.map +1 -0
- package/dist/utils/has-changed.d.ts +2 -0
- package/dist/utils/has-changed.d.ts.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +138 -0
- package/dist/utils/index.js.map +7 -0
- package/dist/utils/index.min.js +1 -0
- package/dist/utils/index.min.js.map +1 -0
- package/dist/utils/index.mjs +115 -0
- package/dist/utils/index.mjs.map +7 -0
- package/lib/flux-store/index.ts +301 -0
- package/lib/hooks/index.ts +52 -101
- package/lib/index.ts +479 -719
- package/lib/native-store/index.ts +106 -0
- package/lib/node/index.ts +5 -3
- package/lib/node/utils/icons.ts +5 -5
- package/lib/node/utils/inline.ts +17 -17
- package/lib/node/utils/node.sw.js +152 -0
- package/lib/node/utils/session-storage.ts +117 -0
- package/lib/node/utils/sw.ts +35 -11
- package/lib/node/utils/tree-adapter.ts +99 -52
- package/lib/pulse-store/index.ts +181 -0
- package/lib/request/index.ts +86 -116
- package/lib/router/index.ts +358 -170
- package/lib/signals/index.ts +98 -0
- package/lib/suspense/index.ts +57 -0
- package/lib/translate/index.ts +156 -0
- package/lib/utils/deep-freeze.ts +54 -0
- package/lib/utils/getter-setter.ts +40 -0
- package/lib/utils/has-changed.ts +43 -0
- package/lib/utils/index.ts +3 -0
- package/package.json +38 -50
- package/tsconfig.json +1 -1
- package/dist/dataset/index.d.ts +0 -24
- package/dist/dataset/index.d.ts.map +0 -1
- package/dist/dataset/index.js +0 -178
- package/dist/dataset/index.js.map +0 -7
- package/dist/dataset/index.mjs +0 -157
- package/dist/dataset/index.mjs.map +0 -7
- package/dist/node/node.sw.tpl +0 -133
- package/dist/node/utils/node.sw.tpl +0 -133
- package/dist/proxy-signal/index.d.ts +0 -23
- package/dist/proxy-signal/index.d.ts.map +0 -1
- package/dist/proxy-signal/index.js +0 -138
- package/dist/proxy-signal/index.js.map +0 -7
- package/dist/proxy-signal/index.mjs +0 -117
- package/dist/proxy-signal/index.mjs.map +0 -7
- package/dist/signal/index.d.ts +0 -20
- package/dist/signal/index.d.ts.map +0 -1
- package/dist/signal/index.js +0 -95
- package/dist/signal/index.js.map +0 -7
- package/dist/signal/index.mjs +0 -74
- package/dist/signal/index.mjs.map +0 -7
- package/dist/store/index.d.ts +0 -16
- package/dist/store/index.d.ts.map +0 -1
- package/dist/store/index.js +0 -93
- package/dist/store/index.js.map +0 -7
- package/dist/store/index.mjs +0 -72
- package/dist/store/index.mjs.map +0 -7
- package/lib/dataset/index.ts +0 -193
- package/lib/index.d.ts +0 -0
- package/lib/interfaces.ts.bak +0 -141
- package/lib/node/utils/node.sw.tpl +0 -133
- package/lib/proxy-signal/index.ts +0 -187
- package/lib/signal/index.ts +0 -161
- package/lib/store/index.ts +0 -101
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { current, updateVnode, Vnode, VnodeWithDom } from "valyrian.js";
|
|
2
|
+
import { get, set, hasChanged } from "valyrian.js/utils";
|
|
3
|
+
|
|
4
|
+
const effectStack: Function[] = [];
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line no-unused-vars
|
|
7
|
+
export type Signal<T> = [() => T, (newValue: T | ((current: T) => T)) => void, () => void];
|
|
8
|
+
|
|
9
|
+
export function createSignal<T>(initialValue: T): Signal<T> {
|
|
10
|
+
let value = initialValue;
|
|
11
|
+
const subscribers = new Set<Function>();
|
|
12
|
+
const vnodesToUpdate = new WeakSet<Vnode>();
|
|
13
|
+
|
|
14
|
+
const runSubscribers = () => subscribers.forEach((subscriber) => subscriber());
|
|
15
|
+
|
|
16
|
+
const read = () => {
|
|
17
|
+
const currentEffect = effectStack[effectStack.length - 1];
|
|
18
|
+
if (currentEffect && !subscribers.has(currentEffect)) {
|
|
19
|
+
subscribers.add(currentEffect);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const currentVnode = current.vnode as VnodeWithDom;
|
|
23
|
+
if (currentVnode && !vnodesToUpdate.has(currentVnode)) {
|
|
24
|
+
const subscription = () => {
|
|
25
|
+
if (!currentVnode.dom) {
|
|
26
|
+
subscribers.delete(subscription);
|
|
27
|
+
vnodesToUpdate.delete(currentVnode);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
updateVnode(currentVnode);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
subscribers.add(subscription);
|
|
34
|
+
vnodesToUpdate.add(currentVnode);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return value;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// eslint-disable-next-line no-unused-vars
|
|
41
|
+
const write = (newValue: T | ((current: T) => T)) => {
|
|
42
|
+
// eslint-disable-next-line no-unused-vars
|
|
43
|
+
const resolvedValue = typeof newValue === "function" ? (newValue as (current: T) => T)(value) : newValue;
|
|
44
|
+
|
|
45
|
+
if (current.event && !current.event.defaultPrevented) {
|
|
46
|
+
current.event.preventDefault();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!hasChanged(value, resolvedValue)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
value = resolvedValue;
|
|
54
|
+
|
|
55
|
+
runSubscribers();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return [read, write, runSubscribers];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createEffect(effect: Function) {
|
|
62
|
+
const runEffect = () => {
|
|
63
|
+
try {
|
|
64
|
+
effectStack.push(runEffect);
|
|
65
|
+
effect();
|
|
66
|
+
} finally {
|
|
67
|
+
effectStack.pop();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
runEffect();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Path is a string with dot notation, e.g:
|
|
75
|
+
// 'a.b.c' === obj.a.b.c
|
|
76
|
+
// 'a.0.c' === obj.a[0].c
|
|
77
|
+
// eslint-disable-next-line no-unused-vars
|
|
78
|
+
export type SignalStore<T> = [() => T, (path: string, newValue: T | ((current: T) => T)) => void];
|
|
79
|
+
|
|
80
|
+
export function createSignalStore<T>(initialState: T): SignalStore<T> {
|
|
81
|
+
const [state, , runSubscribers] = createSignal(initialState);
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line no-unused-vars
|
|
84
|
+
const setter = (path: string, newValue: T | ((current: T) => T)) => {
|
|
85
|
+
const current = get(initialState, path);
|
|
86
|
+
// eslint-disable-next-line no-unused-vars
|
|
87
|
+
const resolvedValue = typeof newValue === "function" ? (newValue as (current: T) => T)(current) : newValue;
|
|
88
|
+
|
|
89
|
+
if (!hasChanged(current, resolvedValue)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
set(initialState, path, resolvedValue);
|
|
94
|
+
runSubscribers();
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return [state, setter];
|
|
98
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ValyrianComponent, Vnode, isVnodeComponent, isPOJOComponent, isComponent, v, Children } from "valyrian.js";
|
|
2
|
+
import { useState } from "valyrian.js/hooks";
|
|
3
|
+
|
|
4
|
+
export function Suspense(
|
|
5
|
+
{
|
|
6
|
+
fallback,
|
|
7
|
+
error
|
|
8
|
+
}: // eslint-disable-next-line no-unused-vars
|
|
9
|
+
{ fallback: any | Vnode | ValyrianComponent; error?: (e: Error) => any | Vnode | ValyrianComponent },
|
|
10
|
+
children: Children
|
|
11
|
+
): ValyrianComponent {
|
|
12
|
+
const [loadedChildren, setLoadedChildren] = useState(null);
|
|
13
|
+
const [err, setErr] = useState(null);
|
|
14
|
+
|
|
15
|
+
return v(() => {
|
|
16
|
+
if (err()) {
|
|
17
|
+
if (error) {
|
|
18
|
+
return error(err());
|
|
19
|
+
}
|
|
20
|
+
return err().message;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (loadedChildren()) {
|
|
24
|
+
return loadedChildren();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Promise.all(
|
|
28
|
+
children.map((child) => {
|
|
29
|
+
if (isVnodeComponent(child)) {
|
|
30
|
+
if (isPOJOComponent(child.tag)) {
|
|
31
|
+
return child.tag.view.bind(child.tag)(child.props || {}, child.children);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return child.tag(child.props || {}, child.children);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isPOJOComponent(child)) {
|
|
38
|
+
return child.view.bind(child)({}, []);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isComponent(child)) {
|
|
42
|
+
return child({}, []);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return child;
|
|
46
|
+
})
|
|
47
|
+
)
|
|
48
|
+
.then((newChildren) => {
|
|
49
|
+
setLoadedChildren(newChildren);
|
|
50
|
+
})
|
|
51
|
+
.catch((e) => {
|
|
52
|
+
setErr(e);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return fallback;
|
|
56
|
+
}, {}) as unknown as ValyrianComponent;
|
|
57
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { directive, setPropNameReserved, update, VnodeWithDom } from "valyrian.js";
|
|
2
|
+
import { get } from "valyrian.js/utils";
|
|
3
|
+
|
|
4
|
+
const translations: Record<string, Record<string, any>> = {};
|
|
5
|
+
let lang = "en";
|
|
6
|
+
|
|
7
|
+
export function t(path: string, params?: Record<string, string>): string {
|
|
8
|
+
const langDef = translations[lang];
|
|
9
|
+
const translation = get(langDef, path);
|
|
10
|
+
|
|
11
|
+
if (typeof translation !== "string") {
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
console.warn(`Translation not found for ${path}`);
|
|
14
|
+
return path;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!params) {
|
|
18
|
+
return translation;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return translation.replace(/{(\w+)}/g, (_, key) => {
|
|
22
|
+
if (key in params) {
|
|
23
|
+
return params[key];
|
|
24
|
+
}
|
|
25
|
+
return `{${key}}`;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function setTranslations(
|
|
30
|
+
defaultTranslation: Record<string, any>,
|
|
31
|
+
newTranslations: Record<string, Record<string, any>> = {}
|
|
32
|
+
) {
|
|
33
|
+
for (const lang in translations) {
|
|
34
|
+
Reflect.deleteProperty(translations, lang);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
translations.en = { ...defaultTranslation };
|
|
38
|
+
|
|
39
|
+
for (const lang in newTranslations) {
|
|
40
|
+
translations[lang] = {
|
|
41
|
+
...defaultTranslation,
|
|
42
|
+
...newTranslations[lang]
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
update();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getTranslations(): Record<string, Record<string, any>> {
|
|
49
|
+
return translations;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function setLang(newLang: string): void {
|
|
53
|
+
if (typeof newLang !== "string") {
|
|
54
|
+
throw new Error(`Language ${newLang} not found`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const parsedLang = newLang.toLowerCase().split("-").shift()?.split("_").shift();
|
|
58
|
+
|
|
59
|
+
if (typeof parsedLang !== "string") {
|
|
60
|
+
throw new Error(`Language ${newLang} not found`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!translations[parsedLang]) {
|
|
64
|
+
throw new Error(`Language ${newLang} not found`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
lang = parsedLang;
|
|
68
|
+
update();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function getLang(): string {
|
|
72
|
+
return lang;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export class NumberFormatter {
|
|
76
|
+
#value: number = 0;
|
|
77
|
+
|
|
78
|
+
get value(): number {
|
|
79
|
+
return this.#value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private constructor() {}
|
|
83
|
+
|
|
84
|
+
public set(newValue: number | string, shiftDecimal = false) {
|
|
85
|
+
this.#value = this.clean(newValue, shiftDecimal);
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private clean(value: string | number, shiftDecimal = false): number {
|
|
90
|
+
let stringNumber = String(value).replace(/[^0-9.-]+/g, "");
|
|
91
|
+
|
|
92
|
+
if (shiftDecimal) {
|
|
93
|
+
stringNumber = stringNumber.replace(/\./g, "");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const number = Number(stringNumber);
|
|
97
|
+
|
|
98
|
+
return isNaN(number) ? 0 : number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
format(digits = 2, options: Intl.NumberFormatOptions = {}, customLocale?: Intl.LocalesArgument): string {
|
|
102
|
+
const lang = customLocale || getLang();
|
|
103
|
+
const formatter = new Intl.NumberFormat(lang as string, {
|
|
104
|
+
style: "currency",
|
|
105
|
+
currency: "USD",
|
|
106
|
+
minimumFractionDigits: digits,
|
|
107
|
+
maximumFractionDigits: digits,
|
|
108
|
+
...options
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return formatter.format(this.#value);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fromDecimalPlaces(decimalPlaces: number) {
|
|
115
|
+
const currentDecimalPlaces = this.getDecimalPlaces();
|
|
116
|
+
const factor = Math.pow(10, decimalPlaces - currentDecimalPlaces);
|
|
117
|
+
this.#value = Number((this.#value / factor).toFixed(decimalPlaces));
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Ex toDecimalPlaces(1) = 123.456 -> 12345.6
|
|
122
|
+
toDecimalPlaces(decimalPlaces: number) {
|
|
123
|
+
const currentDecimalPlaces = this.getDecimalPlaces();
|
|
124
|
+
const factor = Math.pow(10, currentDecimalPlaces - decimalPlaces);
|
|
125
|
+
this.#value = Number((this.#value * factor).toFixed(decimalPlaces));
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getDecimalPlaces(): number {
|
|
130
|
+
if (Math.floor(this.#value) === this.#value) {
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const stringValue = String(this.#value);
|
|
135
|
+
const decimalIndex = stringValue.indexOf(".");
|
|
136
|
+
return decimalIndex === -1 ? 0 : stringValue.length - decimalIndex - 1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
shiftDecimalPlaces() {
|
|
140
|
+
return this.toDecimalPlaces(0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static create(value: number | string = 0, shiftDecimal = false): NumberFormatter {
|
|
144
|
+
const formatter = new NumberFormatter();
|
|
145
|
+
return formatter.set(value, shiftDecimal);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
directive("t", (value: string | null, vnode: VnodeWithDom): void => {
|
|
150
|
+
const keys = typeof value === "string" ? [value] : vnode.children;
|
|
151
|
+
const params = vnode.props["v-t-params"] || {};
|
|
152
|
+
const children = keys.map((key) => (typeof key === "string" && key.trim().length > 1 ? t(key.trim(), params) : key));
|
|
153
|
+
vnode.children = children;
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
setPropNameReserved("v-t-params");
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function deepFreeze(obj: any): any {
|
|
2
|
+
if (typeof obj === "object" && obj !== null && !Object.isFrozen(obj)) {
|
|
3
|
+
if (Array.isArray(obj)) {
|
|
4
|
+
for (let i = 0, l = obj.length; i < l; i++) {
|
|
5
|
+
deepFreeze(obj[i]);
|
|
6
|
+
}
|
|
7
|
+
} else {
|
|
8
|
+
const props = Reflect.ownKeys(obj);
|
|
9
|
+
for (let i = 0, l = props.length; i < l; i++) {
|
|
10
|
+
deepFreeze(obj[props[i]]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// If the object is an instance of a class (not a plain object or array) we need to freeze the prototype
|
|
14
|
+
const proto = Object.getPrototypeOf(obj);
|
|
15
|
+
if (proto && proto !== Object.prototype) {
|
|
16
|
+
deepFreeze(proto);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
Object.freeze(obj);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function deepCloneUnfreeze<T>(obj: T): T {
|
|
26
|
+
if (typeof obj === "undefined" || obj === null || typeof obj !== "object") {
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// If the object is an instance of a class (not a plain object or array) we need to clone it
|
|
31
|
+
// This could not work with classes that have required parameters in the constructor
|
|
32
|
+
if (obj.constructor && obj.constructor !== Object && obj.constructor !== Array) {
|
|
33
|
+
const clone = Reflect.construct(obj.constructor, []);
|
|
34
|
+
|
|
35
|
+
for (const key of Reflect.ownKeys(obj)) {
|
|
36
|
+
const value = (obj as Record<string | symbol, any>)[key];
|
|
37
|
+
(clone as Record<string | symbol, any>)[key] = deepCloneUnfreeze(value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return clone;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (Array.isArray(obj)) {
|
|
44
|
+
return obj.map((item) => deepCloneUnfreeze(item)) as unknown as T;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const clone = {} as T;
|
|
48
|
+
for (const key of Reflect.ownKeys(obj)) {
|
|
49
|
+
const value = (obj as Record<string | symbol, any>)[key];
|
|
50
|
+
(clone as Record<string | symbol, any>)[key] = deepCloneUnfreeze(value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return clone;
|
|
54
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Dot notation: get(obj, 'a.b.c' ) === obj.a.b.c
|
|
2
|
+
// get(obj, 'a.0.c') === obj.a[0].c
|
|
3
|
+
export function get(obj: unknown, path: string, defaultValue?: unknown) {
|
|
4
|
+
if (!path || typeof path !== "string" || !obj || typeof obj !== "object") {
|
|
5
|
+
return defaultValue;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const result = path.split(".").reduce((acc: any, part) => acc && acc?.[part], obj);
|
|
9
|
+
|
|
10
|
+
if (typeof result === "undefined") {
|
|
11
|
+
return defaultValue || null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Dot notation: set(obj, 'a.b.c', value) === obj.a.b.c = value
|
|
18
|
+
// set(obj, 'a.0.c', value) === obj.a[0].c = value
|
|
19
|
+
export function set(obj: any, path: string, value: any) {
|
|
20
|
+
if (!path || typeof path !== "string" || !obj || typeof obj !== "object") {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const parts = path.split(".");
|
|
25
|
+
const last = parts.pop();
|
|
26
|
+
|
|
27
|
+
if (!last) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let target = obj;
|
|
32
|
+
for (const part of parts) {
|
|
33
|
+
if (!target[part]) {
|
|
34
|
+
target[part] = {};
|
|
35
|
+
}
|
|
36
|
+
target = target[part];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
target[last] = value;
|
|
40
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Utility function to check if dependencies have changed recursively
|
|
2
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
3
|
+
export function hasChanged(prev: any, current: any) {
|
|
4
|
+
if (Array.isArray(prev)) {
|
|
5
|
+
if (Array.isArray(current) === false) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (prev.length !== current.length) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
for (let i = 0; i < current.length; i++) {
|
|
14
|
+
if (hasChanged(prev[i], current[i])) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof prev === "object" && prev !== null) {
|
|
23
|
+
if (typeof current !== "object" || current === null) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for (const key in current) {
|
|
28
|
+
if (hasChanged(prev[key], current[key])) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const key in prev) {
|
|
34
|
+
if (hasChanged(prev[key], current[key])) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return Object.is(prev, current) === false;
|
|
43
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valyrian.js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Lightweight steel to forge PWAs. (Minimal Frontend Framework with server side rendering and other capabilities)",
|
|
5
5
|
"repository": "git@github.com:Masquerade-Circus/valyrian.js.git",
|
|
6
6
|
"author": "Masquerade <christian@masquerade-circus.net>",
|
|
@@ -16,15 +16,12 @@
|
|
|
16
16
|
"types": "dist/**/*.d.ts",
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
|
-
"types": "./
|
|
19
|
+
"types": "./lib/index.ts",
|
|
20
20
|
"import": "./dist/index.mjs",
|
|
21
21
|
"require": "./dist/index.js"
|
|
22
22
|
},
|
|
23
|
-
"./lib/*": {
|
|
24
|
-
"import": "./lib/*/index.ts"
|
|
25
|
-
},
|
|
26
23
|
"./*": {
|
|
27
|
-
"types": "./
|
|
24
|
+
"types": "./lib/*/index.ts",
|
|
28
25
|
"import": "./dist/*/index.mjs",
|
|
29
26
|
"require": "./dist/*/index.js"
|
|
30
27
|
}
|
|
@@ -59,70 +56,61 @@
|
|
|
59
56
|
"node": ">=18.0.0"
|
|
60
57
|
},
|
|
61
58
|
"scripts": {
|
|
62
|
-
"dev:source": "NODE_ENV=development
|
|
63
|
-
"dev:test": "
|
|
64
|
-
"dev:test:nyc": "nodemon --enable-source-maps -w ./test -w ./lib -w ./plugins --exec 'nyc --reporter=text --reporter=lcov mocha --timeout 15000 --slow 0 --require ./register \"test/**/*_test.js\"'",
|
|
59
|
+
"dev:source": "NODE_ENV=development chokidar './lib/**/*.ts' -c 'bun run source.js'",
|
|
60
|
+
"dev:test": "bun test --bail --watch",
|
|
65
61
|
"dev:web": "browser-sync start --config 'www/bs-config.js'",
|
|
66
|
-
"build": "
|
|
67
|
-
"build:source": "cross-env NODE_ENV=production
|
|
68
|
-
"test": "cross-env NODE_ENV=development
|
|
69
|
-
"coverage": "nyc report --reporter=lcov",
|
|
62
|
+
"build": "bun run build:source && bun run remark",
|
|
63
|
+
"build:source": "cross-env NODE_ENV=production bun run source.js",
|
|
64
|
+
"test": "cross-env NODE_ENV=development bun test --bail --coverage --coverage-reporter=lcov --coverage-reporter=text",
|
|
70
65
|
"remark": "remark . -o",
|
|
71
|
-
"commit": "git add . && git-cz",
|
|
66
|
+
"commit": "git add . && git-cz && git push",
|
|
72
67
|
"release": "release-it --verbose",
|
|
73
68
|
"release-test": "release-it --dry-run --verbose",
|
|
74
|
-
"
|
|
69
|
+
"update": "ncu -u && bun install"
|
|
75
70
|
},
|
|
76
71
|
"dependencies": {
|
|
77
|
-
"clean-css": "^5.3.
|
|
78
|
-
"esbuild": "^0.
|
|
79
|
-
"favicons": "^7.
|
|
80
|
-
"form-data": "^4.0.
|
|
81
|
-
"purgecss": "^
|
|
72
|
+
"clean-css": "^5.3.3",
|
|
73
|
+
"esbuild": "^0.24.0",
|
|
74
|
+
"favicons": "^7.2.0",
|
|
75
|
+
"form-data": "^4.0.1",
|
|
76
|
+
"purgecss": "^7.0.2",
|
|
82
77
|
"remark": "^15.0.1",
|
|
83
|
-
"terser": "^5.
|
|
84
|
-
"ts-node": "^10.9.
|
|
78
|
+
"terser": "^5.37.0",
|
|
79
|
+
"ts-node": "^10.9.2",
|
|
85
80
|
"tsc-prog": "^2.3.0",
|
|
86
|
-
"tslib": "^2.
|
|
87
|
-
"typescript": "^5.
|
|
81
|
+
"tslib": "^2.8.1",
|
|
82
|
+
"typescript": "^5.7.2"
|
|
88
83
|
},
|
|
89
84
|
"devDependencies": {
|
|
90
|
-
"@release-it/conventional-changelog": "^
|
|
91
|
-
"@types/clean-css": "^4.2.
|
|
92
|
-
"@types/node": "^
|
|
93
|
-
"@types/node-fetch": "^2.6.
|
|
85
|
+
"@release-it/conventional-changelog": "^9.0.3",
|
|
86
|
+
"@types/clean-css": "^4.2.11",
|
|
87
|
+
"@types/node": "^22.10.1",
|
|
88
|
+
"@types/node-fetch": "^2.6.12",
|
|
94
89
|
"@types/sharp": "^0.32.0",
|
|
95
90
|
"@types/source-map": "^0.5.7",
|
|
96
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
97
|
-
"@typescript-eslint/parser": "^
|
|
91
|
+
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
|
92
|
+
"@typescript-eslint/parser": "^8.18.0",
|
|
98
93
|
"buffalo-test": "^2.0.0",
|
|
99
|
-
"
|
|
94
|
+
"chokidar-cli": "^3.0.0",
|
|
95
|
+
"compression": "^1.7.5",
|
|
100
96
|
"cross-env": "^7.0.3",
|
|
101
97
|
"cz-conventional-changelog": "^3.3.0",
|
|
102
|
-
"dayjs": "^1.11.
|
|
103
|
-
"eslint": "^
|
|
104
|
-
"eslint-plugin-sonarjs": "^0.
|
|
98
|
+
"dayjs": "^1.11.13",
|
|
99
|
+
"eslint": "^9.16.0",
|
|
100
|
+
"eslint-plugin-sonarjs": "^3.0.1",
|
|
105
101
|
"expect": "^29.7.0",
|
|
106
|
-
"fastify": "^
|
|
102
|
+
"fastify": "^5.1.0",
|
|
107
103
|
"gzip-size": "^7.0.0",
|
|
108
|
-
"
|
|
109
|
-
"nodemon": "^3.0.1",
|
|
110
|
-
"nyc": "^15.1.0",
|
|
104
|
+
"npm-check-updates": "^17.1.11",
|
|
111
105
|
"pirates": "^4.0.6",
|
|
112
|
-
"release-it": "^
|
|
113
|
-
"remark-cli": "^
|
|
106
|
+
"release-it": "^17.10.0",
|
|
107
|
+
"remark-cli": "^12.0.1",
|
|
114
108
|
"remark-toc": "^9.0.0"
|
|
115
109
|
},
|
|
116
110
|
"overrides": {
|
|
117
111
|
"minimist": "^1.2.8",
|
|
118
112
|
"source-map-support": "^0.5.21"
|
|
119
113
|
},
|
|
120
|
-
"nyc": {
|
|
121
|
-
"exclude": [
|
|
122
|
-
"test",
|
|
123
|
-
"register.js"
|
|
124
|
-
]
|
|
125
|
-
},
|
|
126
114
|
"remarkConfig": {
|
|
127
115
|
"plugins": [
|
|
128
116
|
"toc"
|
|
@@ -203,14 +191,14 @@
|
|
|
203
191
|
},
|
|
204
192
|
"hooks": {
|
|
205
193
|
"before:init": [
|
|
206
|
-
"
|
|
207
|
-
"
|
|
194
|
+
"bun run build",
|
|
195
|
+
"bun run test"
|
|
208
196
|
],
|
|
209
197
|
"after:bump": [
|
|
210
|
-
"
|
|
198
|
+
"bun run remark"
|
|
211
199
|
],
|
|
212
200
|
"after:@release-it/conventional-changelog": [
|
|
213
|
-
"
|
|
201
|
+
"bun run remark"
|
|
214
202
|
]
|
|
215
203
|
}
|
|
216
204
|
}
|
package/tsconfig.json
CHANGED
package/dist/dataset/index.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { VnodeInterface, VnodeWithDom } from "valyrian.js";
|
|
2
|
-
interface DataSetInterface<T> {
|
|
3
|
-
data: T[];
|
|
4
|
-
reset: (data: T[]) => void;
|
|
5
|
-
add: (...data: T[]) => void;
|
|
6
|
-
update: (index: number, data: T) => void;
|
|
7
|
-
delete: (index: number) => void;
|
|
8
|
-
}
|
|
9
|
-
interface DataSetHandler<T> {
|
|
10
|
-
(data: T, index: number): VnodeInterface;
|
|
11
|
-
}
|
|
12
|
-
export declare class DataSet<T> implements DataSetInterface<T> {
|
|
13
|
-
#private;
|
|
14
|
-
get data(): T[];
|
|
15
|
-
set data(data: T[]);
|
|
16
|
-
constructor(data?: T[], shouldFreeze?: boolean);
|
|
17
|
-
setVnodeAndHandler(vnode: VnodeWithDom, handler: DataSetHandler<T>): void;
|
|
18
|
-
reset(data: T[]): void;
|
|
19
|
-
add(...data: T[]): void;
|
|
20
|
-
delete(index: number): void;
|
|
21
|
-
update(index: number, item: Partial<T>): void;
|
|
22
|
-
}
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/dataset/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAwD,MAAM,aAAa,CAAC;AAEjH,UAAU,gBAAgB,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,EAAE,CAAC;IAEV,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAE3B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAE5B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAEzC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AACD,UAAU,cAAc,CAAC,CAAC;IAExB,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC;CAC1C;AAoBD,qBAAa,OAAO,CAAC,CAAC,CAAE,YAAW,gBAAgB,CAAC,CAAC,CAAC;;IAQpD,IAAI,IAAI,IAQO,CAAC,EAAE,CAFjB;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAEjB;gBAqBW,IAAI,GAAE,CAAC,EAAO,EAAE,YAAY,UAAO;IAK/C,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IAMlE,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE;IA2Cf,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;IA4BhB,MAAM,CAAC,KAAK,EAAE,MAAM;IAcpB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;CAgBvC"}
|