rumious 1.0.12 → 2.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/dist/app/app.d.ts +10 -8
- package/dist/app/index.d.ts +0 -1
- package/dist/component/component.d.ts +15 -22
- package/dist/component/element.d.ts +10 -15
- package/dist/global.d.ts +15 -0
- package/dist/index.d.ts +7 -27
- package/dist/index.js +1037 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx/component.d.ts +3 -0
- package/dist/jsx/dynamic.d.ts +2 -0
- package/dist/jsx/element.d.ts +9 -0
- package/dist/jsx/index.d.ts +4 -4
- package/dist/jsx/template.d.ts +25 -0
- package/dist/{app/module.d.ts → module/index.d.ts} +1 -1
- package/dist/ref/index.d.ts +1 -2
- package/dist/ref/ref.d.ts +37 -0
- package/dist/render/context.d.ts +7 -9
- package/dist/render/index.d.ts +4 -3
- package/dist/render/list.d.ts +16 -0
- package/dist/render/render.d.ts +3 -2
- package/dist/render/view.d.ts +19 -0
- package/dist/state/index.d.ts +1 -2
- package/dist/state/list.d.ts +14 -0
- package/dist/state/reactor.d.ts +15 -16
- package/dist/state/state.d.ts +11 -8
- package/dist/types/component.d.ts +5 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/jsx.d.ts +16 -8
- package/dist/types/state.d.ts +8 -0
- package/dist/types/template.d.ts +5 -0
- package/dist/utils/checker.d.ts +2 -0
- package/package.json +34 -53
- package/rollup.config.js +21 -0
- package/src/app/app.ts +45 -0
- package/src/app/index.ts +1 -0
- package/src/component/component.ts +69 -0
- package/src/component/element.ts +76 -0
- package/src/component/index.ts +2 -0
- package/src/global.ts +20 -0
- package/src/index.ts +13 -0
- package/src/jsx/component.ts +17 -0
- package/src/jsx/dynamic.ts +87 -0
- package/src/jsx/element.ts +70 -0
- package/src/jsx/index.ts +7 -0
- package/src/jsx/template.ts +377 -0
- package/src/module/index.ts +7 -0
- package/src/ref/index.ts +1 -0
- package/src/ref/ref.ts +178 -0
- package/src/render/context.ts +11 -0
- package/src/render/index.ts +4 -0
- package/src/render/list.ts +115 -0
- package/src/render/render.ts +31 -0
- package/src/render/view.ts +101 -0
- package/src/state/index.ts +2 -0
- package/src/state/list.ts +96 -0
- package/src/state/reactor.ts +65 -0
- package/src/state/state.ts +68 -0
- package/src/types/component.ts +6 -0
- package/src/types/index.ts +3 -0
- package/src/types/state.ts +16 -0
- package/src/types/template.ts +7 -0
- package/src/utils/checker.ts +5 -0
- package/tsconfig.json +20 -0
- package/README.md +0 -7
- package/dist/context/context.d.ts +0 -12
- package/dist/context/index.d.ts +0 -1
- package/dist/index.cjs +0 -1
- package/dist/index.esm.js +0 -1
- package/dist/index.global.d.ts +0 -46
- package/dist/index.min.js +0 -1
- package/dist/performance/index.d.ts +0 -5
- package/dist/ref/children.d.ts +0 -23
- package/dist/ref/element.d.ts +0 -49
- package/dist/render/array.d.ts +0 -21
- package/dist/render/directives.d.ts +0 -1
- package/dist/render/dynamic.d.ts +0 -2
- package/dist/render/injector.d.ts +0 -15
- package/dist/render/struct.d.ts +0 -85
- package/dist/render/template.d.ts +0 -5
- package/dist/state/array.d.ts +0 -22
- package/dist/state/object.d.ts +0 -31
- package/dist/types/render.d.ts +0 -5
- package/dist/types/utils.d.ts +0 -1
- package/dist/utils/checkers.d.ts +0 -1
- package/dist/utils/name.d.ts +0 -2
- package/dist/utils/oberve.d.ts +0 -1
@@ -0,0 +1,31 @@
|
|
1
|
+
import { RumiousRenderContext } from './context.js';
|
2
|
+
import { RumiousTemplate } from '../types/index.js';
|
3
|
+
|
4
|
+
export function render(
|
5
|
+
content: RumiousTemplate,
|
6
|
+
container:HTMLElement,
|
7
|
+
context:RumiousRenderContext
|
8
|
+
):HTMLElement{
|
9
|
+
context.onRendered = [];
|
10
|
+
let result = content(container,context);
|
11
|
+
|
12
|
+
for (var i = 0; i < context.onRendered.length; i++) {
|
13
|
+
context.onRendered[i]();
|
14
|
+
}
|
15
|
+
return result;
|
16
|
+
}
|
17
|
+
|
18
|
+
export function renderFrag(
|
19
|
+
content: RumiousTemplate,
|
20
|
+
context: RumiousRenderContext
|
21
|
+
): HTMLElement {
|
22
|
+
let container = document.createDocumentFragment();
|
23
|
+
context.onRendered = [];
|
24
|
+
let result = content(container, context);
|
25
|
+
|
26
|
+
for (var i = 0; i < context.onRendered.length; i++) {
|
27
|
+
context.onRendered[i]();
|
28
|
+
}
|
29
|
+
|
30
|
+
return result;
|
31
|
+
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
import { RumiousTemplate } from '../types/index.js';
|
2
|
+
import { RumiousRenderContext } from './context.js';
|
3
|
+
import { render, renderFrag } from './render.js';
|
4
|
+
|
5
|
+
export interface RumiousViewControlTarget {
|
6
|
+
element: HTMLElement,
|
7
|
+
context: RumiousRenderContext
|
8
|
+
}
|
9
|
+
|
10
|
+
export class RumiousViewControl {
|
11
|
+
private targets: RumiousViewControlTarget[] = [];
|
12
|
+
|
13
|
+
constructor() {}
|
14
|
+
|
15
|
+
addTarget(target: RumiousViewControlTarget) {
|
16
|
+
this.targets.push(target);
|
17
|
+
}
|
18
|
+
|
19
|
+
|
20
|
+
setView(template: RumiousTemplate) {
|
21
|
+
|
22
|
+
const targets = this.targets;
|
23
|
+
|
24
|
+
if (targets.length === 0) {
|
25
|
+
throw new Error(`RumiousRenderError: No target assigned to ViewControl`);
|
26
|
+
}
|
27
|
+
|
28
|
+
for (let i = 0; i < targets.length; i++) {
|
29
|
+
render(template, targets[i].element, targets[i].context);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
removeChild(index: number) {
|
34
|
+
for (let i = 0; i < this.targets.length; i++) {
|
35
|
+
let parent = this.targets[i].element.parentElement;
|
36
|
+
if (!parent) return;
|
37
|
+
let element = parent.children[index];
|
38
|
+
if (element) parent.removeChild(element);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
addChild(
|
43
|
+
template: RumiousTemplate,
|
44
|
+
prepend: boolean = false
|
45
|
+
) {
|
46
|
+
const targets = this.targets;
|
47
|
+
if (targets.length === 0) {
|
48
|
+
throw new Error(`RumiousRenderError: No target assigned to ViewControl`);
|
49
|
+
}
|
50
|
+
|
51
|
+
for (let i = 0; i < targets.length; i++) {
|
52
|
+
let templ = renderFrag(template, targets[i].context);
|
53
|
+
if (!prepend) targets[i].element.appendChild(templ);
|
54
|
+
else targets[i].element.prepend(templ);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
each(callback: (target: RumiousViewControlTarget) => any) {
|
60
|
+
for (let target of this.targets) {
|
61
|
+
callback(target);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
emptyAll() {
|
66
|
+
const targets = this.targets;
|
67
|
+
for (let i = 0; i < targets.length; i++) {
|
68
|
+
targets[i].element.textContent = '';
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
empty(target: HTMLElement) {
|
73
|
+
const targets = this.targets;
|
74
|
+
for (let i = 0; i < targets.length; i++) {
|
75
|
+
if (targets[i].element === target) {
|
76
|
+
target.textContent = '';
|
77
|
+
return;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
updateChild(index: number, template: RumiousTemplate) {
|
83
|
+
for (let i = 0; i < this.targets.length; i++) {
|
84
|
+
const { element, context } = this.targets[i];
|
85
|
+
const parent = element.parentElement;
|
86
|
+
if (!parent) continue;
|
87
|
+
|
88
|
+
const oldChild = parent.children[index];
|
89
|
+
const newNode = renderFrag(template, context);
|
90
|
+
|
91
|
+
if (oldChild) {
|
92
|
+
parent.replaceChild(newNode, oldChild);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
}
|
98
|
+
|
99
|
+
export function createViewControl(): RumiousViewControl {
|
100
|
+
return new RumiousViewControl();
|
101
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
import { RumiousState } from './state.js';
|
2
|
+
import { RumiousReactor } from './reactor.js';
|
3
|
+
|
4
|
+
export class RumiousListState < T > extends RumiousState < T[] > {
|
5
|
+
constructor(
|
6
|
+
value: T[] = [],
|
7
|
+
reactor ? : RumiousReactor < RumiousState < T[] >>
|
8
|
+
) {
|
9
|
+
super(value, reactor);
|
10
|
+
}
|
11
|
+
|
12
|
+
append(value: T) {
|
13
|
+
this.value.push(value);
|
14
|
+
this.reactor?.notify({
|
15
|
+
type: 'append',
|
16
|
+
state: this,
|
17
|
+
key:this.value.length -1 ,
|
18
|
+
value
|
19
|
+
});
|
20
|
+
}
|
21
|
+
|
22
|
+
prepend(value: T) {
|
23
|
+
this.value.unshift(value);
|
24
|
+
this.reactor?.notify({
|
25
|
+
type: 'prepend',
|
26
|
+
state: this,
|
27
|
+
key:0,
|
28
|
+
value
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
insert(pos: number, value: T) {
|
33
|
+
this.value.splice(pos, 0, value);
|
34
|
+
this.reactor?.notify({
|
35
|
+
type: 'insert',
|
36
|
+
state: this,
|
37
|
+
value,
|
38
|
+
key: pos
|
39
|
+
});
|
40
|
+
}
|
41
|
+
|
42
|
+
updateAt(pos: number, value: T) {
|
43
|
+
this.value[pos] = value;
|
44
|
+
this.reactor?.notify({
|
45
|
+
type: 'update',
|
46
|
+
state: this,
|
47
|
+
value,
|
48
|
+
key: pos
|
49
|
+
});
|
50
|
+
}
|
51
|
+
|
52
|
+
remove(pos: number) {
|
53
|
+
let currentValue = this.value[pos];
|
54
|
+
this.value.splice(pos, 1);
|
55
|
+
this.reactor?.notify({
|
56
|
+
type: 'remove',
|
57
|
+
state: this,
|
58
|
+
value: currentValue,
|
59
|
+
key: pos
|
60
|
+
});
|
61
|
+
}
|
62
|
+
|
63
|
+
clear() {
|
64
|
+
this.value.length = 0;
|
65
|
+
this.reactor?.notify({
|
66
|
+
type: 'set',
|
67
|
+
state: this,
|
68
|
+
value: []
|
69
|
+
});
|
70
|
+
}
|
71
|
+
|
72
|
+
reverse() {
|
73
|
+
this.value.reverse();
|
74
|
+
this.reactor?.notify({
|
75
|
+
type: 'set',
|
76
|
+
state: this,
|
77
|
+
value: this.value
|
78
|
+
});
|
79
|
+
}
|
80
|
+
|
81
|
+
filter(predicate: (item: T, index: number, array: T[]) => boolean) {
|
82
|
+
this.value = this.value.filter(predicate);
|
83
|
+
this.reactor?.notify({
|
84
|
+
type: 'set',
|
85
|
+
state: this,
|
86
|
+
value: this.value
|
87
|
+
});
|
88
|
+
}
|
89
|
+
|
90
|
+
}
|
91
|
+
|
92
|
+
export function createListState<T>(
|
93
|
+
values:T[]
|
94
|
+
):RumiousListState<T>{
|
95
|
+
return new RumiousListState(values);
|
96
|
+
}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { RumiousStateBind, RumiousChangeCommit } from '../types/index.js';
|
2
|
+
|
3
|
+
export class RumiousReactor < T = any > {
|
4
|
+
private bindings: RumiousStateBind < T > [] = [];
|
5
|
+
private internal: RumiousStateBind < T > [] = [];
|
6
|
+
public isUIBatch = true;
|
7
|
+
private scheduled = false;
|
8
|
+
private queuedCommits: RumiousChangeCommit < T > [] = [];
|
9
|
+
|
10
|
+
|
11
|
+
constructor(public target: T) {}
|
12
|
+
|
13
|
+
addBinding(binding: RumiousStateBind < T > ): void {
|
14
|
+
this.bindings.push(binding);
|
15
|
+
}
|
16
|
+
|
17
|
+
removeBinding(binding: RumiousStateBind < T > ): void {
|
18
|
+
this.bindings = this.bindings.filter(b => b !== binding);
|
19
|
+
}
|
20
|
+
|
21
|
+
addInternalBinding(binding: RumiousStateBind < T > ): void {
|
22
|
+
this.internal.push(binding);
|
23
|
+
}
|
24
|
+
|
25
|
+
removeInternalBinding(binding: RumiousStateBind < T > ): void {
|
26
|
+
this.internal = this.internal.filter(b => b !== binding);
|
27
|
+
}
|
28
|
+
|
29
|
+
notify(commit: RumiousChangeCommit < T > ): void {
|
30
|
+
for (const binding of this.bindings) {
|
31
|
+
binding(commit);
|
32
|
+
}
|
33
|
+
|
34
|
+
if (this.isUIBatch) {
|
35
|
+
this.scheduleInternalUpdate(commit);
|
36
|
+
} else {
|
37
|
+
for (const binding of this.internal) {
|
38
|
+
binding(commit);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
private scheduleInternalUpdate(commit: RumiousChangeCommit < T > ) {
|
45
|
+
this.queuedCommits.push(commit);
|
46
|
+
|
47
|
+
if (!this.scheduled) {
|
48
|
+
this.scheduled = true;
|
49
|
+
queueMicrotask(() => {
|
50
|
+
this.flushInternal();
|
51
|
+
});
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
private flushInternal() {
|
56
|
+
const lastCommit = this.queuedCommits[this.queuedCommits.length - 1];
|
57
|
+
|
58
|
+
for (const binding of this.internal) {
|
59
|
+
binding(lastCommit); // chỉ gửi commit cuối cùng
|
60
|
+
}
|
61
|
+
|
62
|
+
this.queuedCommits = [];
|
63
|
+
this.scheduled = false;
|
64
|
+
}
|
65
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { RumiousReactor } from './reactor.js';
|
2
|
+
import { RumiousStateBind } from '../types/index.js';
|
3
|
+
|
4
|
+
export class RumiousState < T > {
|
5
|
+
|
6
|
+
constructor(
|
7
|
+
public value: T,
|
8
|
+
public reactor ? : RumiousReactor < RumiousState < T >>
|
9
|
+
) {
|
10
|
+
|
11
|
+
if (!this.reactor) {
|
12
|
+
this.reactor = new RumiousReactor < RumiousState < T >> (this);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
set(value: T) {
|
17
|
+
this.value = value;
|
18
|
+
this.reactor?.notify({
|
19
|
+
type: 'set',
|
20
|
+
value: value,
|
21
|
+
state: this
|
22
|
+
});
|
23
|
+
}
|
24
|
+
|
25
|
+
get(): T {
|
26
|
+
return this.value;
|
27
|
+
}
|
28
|
+
|
29
|
+
slientUpdate(value: T) {
|
30
|
+
this.value = value;
|
31
|
+
}
|
32
|
+
|
33
|
+
update(updater: (value: T) => T) {
|
34
|
+
this.set(updater(this.value));
|
35
|
+
}
|
36
|
+
|
37
|
+
toJSON(): string {
|
38
|
+
return JSON.stringify(this.value);
|
39
|
+
}
|
40
|
+
|
41
|
+
trigger() {
|
42
|
+
this.reactor?.notify({
|
43
|
+
type: 'set',
|
44
|
+
value: this.value,
|
45
|
+
state: this
|
46
|
+
});
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
export function createState < T > (value: T): RumiousState < T > {
|
51
|
+
return new RumiousState < T > (value);
|
52
|
+
}
|
53
|
+
|
54
|
+
type StateBindFor < M > = RumiousStateBind < RumiousState < M >> ;
|
55
|
+
|
56
|
+
export function watch < M > (
|
57
|
+
state: RumiousState < M > ,
|
58
|
+
callback: StateBindFor < M >
|
59
|
+
) {
|
60
|
+
if (state.reactor) state.reactor.addBinding(callback);
|
61
|
+
}
|
62
|
+
|
63
|
+
export function unwatch < M > (
|
64
|
+
state: RumiousState < M > ,
|
65
|
+
callback: StateBindFor < M >
|
66
|
+
) {
|
67
|
+
if (state.reactor) state.reactor.removeBinding(callback);
|
68
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
export type RumiousChangeCommitType =
|
2
|
+
| 'set'
|
3
|
+
| 'append'
|
4
|
+
| 'prepend'
|
5
|
+
| 'insert'
|
6
|
+
| 'update'
|
7
|
+
| 'remove'
|
8
|
+
|
9
|
+
export interface RumiousChangeCommit<T> {
|
10
|
+
state:T;
|
11
|
+
type:RumiousChangeCommitType;
|
12
|
+
value:any;
|
13
|
+
key?:number;
|
14
|
+
}
|
15
|
+
|
16
|
+
export type RumiousStateBind < T = any > = (commit:RumiousChangeCommit<T>) => void;
|
package/tsconfig.json
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "esnext",
|
4
|
+
"module": "esnext",
|
5
|
+
"outDir": "./dist",
|
6
|
+
"esModuleInterop": true,
|
7
|
+
"sourceMap":false,
|
8
|
+
"allowSyntheticDefaultImports": true,
|
9
|
+
"moduleResolution": "node",
|
10
|
+
"resolveJsonModule": true,
|
11
|
+
"skipLibCheck": true,
|
12
|
+
"declaration": true,
|
13
|
+
"strict": true,
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
15
|
+
"paths": {
|
16
|
+
"rumious-compiler": ["../compiler/dist/index.d.ts"]
|
17
|
+
}
|
18
|
+
},
|
19
|
+
"include": ["./src", "./src/global.d.ts"]
|
20
|
+
}
|
package/README.md
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
export declare class RumiousContext<T extends object> {
|
2
|
-
events: Record<string, Function[]>;
|
3
|
-
values: Partial<T>;
|
4
|
-
constructor(initialValues?: Partial<T>);
|
5
|
-
has<K extends keyof T>(key: K): boolean;
|
6
|
-
set<K extends keyof T>(key: K, value: T[K]): void;
|
7
|
-
get<K extends keyof T>(key: K): T[K] | undefined;
|
8
|
-
on(event: string, callback: Function): void;
|
9
|
-
off(event: string, callback: Function): void;
|
10
|
-
emit(event: string, payload: any): void;
|
11
|
-
}
|
12
|
-
export declare function createContext<T extends object>(values: T, name?: string): RumiousContext<T>;
|
package/dist/context/index.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export * from './context.js';
|
package/dist/index.cjs
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
var t=require("mutative");class e{constructor(t,e){this.target=t,this.app=e,this.onRenderFinished=[]}findName(t){return this.target[t]}}function n(t,e,s){let r=e.generator.bind(t.target);t.renderHelper=n,r(s,t),setTimeout((async()=>{const e=[...t.onRenderFinished];t.onRenderFinished=[];for(const t of e)await t()}),0)}class s extends HTMLElement{constructor(){super(),this.props={}}setContext(t){this.context=t}setComponent(t){this.componentConstructor=t}setup(t,e){this.context=t,this.componentConstructor=e}connectedCallback(){this.componentConstructor?(this.componentInstance=new this.componentConstructor,this.componentInstance.element=this,this.componentConstructor.classNames&&(this.className=this.componentConstructor.classNames),this.componentInstance.prepare(this.context,this.props),this.componentInstance.onCreate(),this.componentInstance.requestRender()):console.warn("Rumious: Cannot find matching component constructor.")}disconnectedCallback(){this.componentInstance?.onDestroy()}}class r{constructor(t,n={}){this.root=t,this.options=n,this.modules=[],this.context=new e(this,this)}addModule(t,e){const n=t.init(this,e);return this.modules.push(n),n}render(t){n(this.context,t,this.root)}}class i{constructor(t){this.generator=t}}class o{constructor(t){if(this.contents=t,this.targets=new Map,!t||0===t.length)throw new Error("Injector must be initialized with non-empty content");const e=t[0];this.type="string"==typeof e?"string":"element"}commit(t){this.contents=t;const e=t[0];this.type="string"==typeof e?"string":"element"}addTarget(t){this.targets.set(t,1)}inject(t){if(this.targets.has(t)&&this.contents)if(t.innerHTML="","string"===this.type)for(const e of this.contents)t.insertAdjacentHTML("beforeend",e);else for(const e of this.contents)t.appendChild(e)}injectAll(){for(const t of this.targets.keys())this.inject(t)}removeTarget(t){this.targets.delete(t)}clear(){this.targets.clear()}}class a{constructor(t){this.target=t}getElement(){return this.target}remove(){this.target.remove()}addChild(t){this.target.appendChild(t)}listChild(){return this.target.childNodes}querySelector(t){return this.target.querySelector(t)}querySelectorAll(t){return this.target.querySelectorAll(t)}set text(t){this.target.textContent=t}get text(){return this.target.textContent}set value(t){(this.target instanceof HTMLInputElement||this.target instanceof HTMLTextAreaElement)&&(this.target.value=t)}get value(){if(this.target instanceof HTMLInputElement||this.target instanceof HTMLTextAreaElement)return this.target.value}addClassName(t){this.target.classList.add(t)}removeClassName(t){this.target.classList.remove(t)}hasClassName(t){return this.target.classList.contains(t)}toggleClass(t,e){return this.target.classList.toggle(t,e)}setStyle(t){Object.assign(this.target.style,t)}getStyle(t){return getComputedStyle(this.target).getPropertyValue(t)}setAttribute(t,e){this.target.setAttribute(t,e)}getAttribute(t){return this.target.getAttribute(t)}removeAttribute(t){this.target.removeAttribute(t)}on(t,e,n){this.target.addEventListener(t,e,n)}off(t,e,n){this.target.removeEventListener(t,e,n)}set html(t){this.target.innerHTML=t}get html(){return this.target.innerHTML}getBoundingRect(){return this.target.getBoundingClientRect()}isInViewport(){const t=this.target.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}prependChild(t){this.target.prepend(t)}setDisabled(t){(this.target instanceof HTMLButtonElement||this.target instanceof HTMLInputElement||this.target instanceof HTMLTextAreaElement)&&(this.target.disabled=t)}addClasses(...t){this.target.classList.add(...t)}removeClasses(...t){this.target.classList.remove(...t)}replaceClass(t,e){this.target.classList.replace(t,e)}moveTo(t){t.appendChild(this.target)}getParent(){return this.target.parentElement}getNextSibling(){return this.target.nextElementSibling}getPreviousSibling(){return this.target.previousElementSibling}hide(){this.target.style.display="none"}show(){this.target.style.removeProperty("display")}isHidden(){return"none"===window.getComputedStyle(this.target).display}scrollIntoView(t={behavior:"smooth"}){this.target.scrollIntoView(t)}matches(t){return this.target.matches(t)}getChildren(){return Array.from(this.target.children)}insertAfter(t){this.target.parentNode&&this.target.parentNode.insertBefore(t,this.target.nextSibling)}insertBefore(t){this.target.parentNode&&this.target.parentNode.insertBefore(t,this.target)}clearChildren(){for(;this.target.firstChild;)this.target.removeChild(this.target.firstChild)}animate(t,e){return this.target.animate(t,e)}}function h(t){const e=t.indexOf("$");return-1!==e?t.slice(e+1):""}class l{constructor(t){this.target=t,this.bindings=[]}addBinding(t){this.bindings.push(t)}removeBinding(t){this.bindings=this.bindings.filter((e=>e!==t))}async emit(t){await Promise.allSettled(this.bindings.map((e=>{try{const n=e(t);return n instanceof Promise?n:Promise.resolve(n)}catch(t){return Promise.reject(t)}})))}}class c{constructor(t,e){this.value=t,this.reactor=e??new l(this)}set(t){this.value=t,this.reactor.emit({type:"SET",target:this,value:t})}get(){return this.value}increase(t=1){"number"==typeof this.value&&this.set(this.value+t)}produce(e){const[n,s]=t.create(this.value);e(n),this.set(s())}}function u(t,e){t.reactor.addBinding(e)}function d(t,e){t.reactor.removeBinding(e)}const g={on:function(t,e,n,s){"string"==typeof s&&(s=t.findName(h(s))),e.addEventListener(n,s)},ref:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(h(s))),!(s instanceof a))throw Error("Rumious: ref directive required RumiousElementRef !");s.target=e},inject:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(h(s))),!(s instanceof o))throw Error("Rumious: inject directive required RumiousInjector !");s.addTarget(e),s.inject(e)},bind:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(h(s))),!(s instanceof c))throw Error("Rumious: bind directive requires RumiousState!");{const t={text:(t,e)=>e.textContent=t,html:(t,e)=>e.innerHTML=t,value:(t,e)=>e.value=t,class:(t,e)=>e.className=t,style:(t,e)=>e.style.cssText=t,checked:(t,e)=>e.checked=t,disabled:(t,e)=>{"disabled"in e&&(e.disabled=t)},readonly:(t,e)=>e.readOnly=t,required:(t,e)=>e.required=t,selected:(t,e)=>e.selected=t,src:(t,e)=>e.src=t,href:(t,e)=>e.href=t,placeholder:(t,e)=>e.placeholder=t,title:(t,e)=>e.title=t,show:(t,e)=>e.style.display=t?"":"none",hide:(t,e)=>e.style.display=t?"none":""}[n]??((t,e)=>e.setAttribute(n,t));t(s.value,e),s.reactor.addBinding((()=>t(s.value,e)))}},model:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(h(s))),!(s instanceof c&&(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)))throw Error("Rumious: model directive requires RumiousState and a valid form element!");{const t=e.type;e.addEventListener("input",(()=>{if(e instanceof HTMLInputElement)switch(t){case"checkbox":s.set(e.checked);break;case"radio":e.checked&&s.set(e.value);break;default:s.set(e.value)}else(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&s.set(e.value)}))}}};class m{constructor(t,e){this.state=t,this.callback=e}prepare(t,e){this.anchorElement=t,this.context=e}renderItem(t,e){const n=document.createDocumentFragment(),s=this.callback(t,e);return this.context.renderHelper(this.context,s,n),n}scheduleRenderAll(){requestAnimationFrame((()=>this.renderAll()))}async render(){this.state.reactor.addBinding(this.onStateChange.bind(this)),this.scheduleRenderAll()}renderAll(){const t=document.createDocumentFragment();this.state.value.forEach(((e,n)=>{t.appendChild(this.renderItem(e,n))})),this.anchorElement.replaceChildren(t)}updateElement(t,e){const n=this.anchorElement.children[t];n&&this.anchorElement.replaceChild(this.renderItem(e,t),n)}insertOrAppendElement(t,e){const n=this.renderItem(t,e),s=this.anchorElement.children[e];s?this.anchorElement.insertBefore(n,s):this.anchorElement.appendChild(n)}removeElement(t){this.anchorElement.children[t]?.remove()}appendElement(t,e){if(Array.isArray(t)){const n=document.createDocumentFragment();t.forEach(((t,s)=>{n.appendChild(this.renderItem(t,e+s))})),this.anchorElement.replaceChildren(n),this.anchorElement.appendChild(n)}}async onStateChange(t){if(document.contains(this.anchorElement))switch(t.type){case"SET":default:this.scheduleRenderAll();break;case"SET_BY_KEY":this.updateElement(t.key,t.value);break;case"REMOVE_BY_KEY":this.removeElement(t.key);break;case"INSERT_BY_KEY":this.insertOrAppendElement(t.value,t.key);break;case"APPEND":this.appendElement(t.value,this.state.value.length-t.value.length);break;case"PREPEND":this.anchorElement.prepend(this.renderItem(t.value,0))}else this.state.reactor.removeBinding(this.onStateChange.bind(this))}}class p extends m{isLoading=!1;constructor(t){super(t.data,t.template),this.options=t,this.limit=t.limit??50,this.offset=t.offset??0,this.onScroll=this.handleScroll.bind(this),this.onControl=this.handleControl.bind(this),this.onChange=this.handleStateChange.bind(this)}setState(t){this.options.state?.set(t)}async fetchData(){const t=await(this.options.loader?.(this.limit,this.offset))??[];return this.offset+=t.length,t}getScrollInfo(){const t=this.options.scrollElement;return t===window?{scrollTop:window.scrollY,scrollHeight:document.documentElement.scrollHeight,clientHeight:window.innerHeight}:{scrollTop:t.scrollTop,scrollHeight:t.scrollHeight,clientHeight:t.clientHeight}}async addData(){const t=this.options.scrollElement;this.isLoading=!0,this.setState("START_FETCH");const e=await this.fetchData();this.setState("END_FETCH"),0===e.length?(this.setState("NO_DATA"),t.removeEventListener("scroll",this.onScroll)):this.state.append(...e),this.isLoading=!1}async handleScroll(){const{scrollTop:t,scrollHeight:e,clientHeight:n}=this.getScrollInfo();t+n>=e-this.options.threshold&&!this.isLoading&&await this.addData()}handleControl(){"FETCH"===this.options?.controller?.get()&&this.addData()}handleStateChange(t){if(!document.contains(this.anchorElement))return this.options.controller&&d(this.options.controller,this.onControl),void this.state.reactor.removeBinding(this.onChange);this.onStateChange(t)}async render(){this.options.scrollElement.addEventListener("scroll",this.onScroll),this.options.controller&&u(this.options.controller,this.onControl),this.state.reactor.addBinding(this.onChange),this.scheduleRenderAll()}}class f extends m{constructor(t){super(t.data,t.template),this.options=t,this.size=t.size,this.currentPage=t.page??0}getPageData(){const t=this.currentPage*this.size,e=t+this.size;return this.state.value.slice(t,e)}renderPage(){const t=document.createDocumentFragment(),e=this.currentPage*this.size,n=e+this.size;this.state.value.slice(e,n).forEach(((n,s)=>{t.appendChild(this.renderItem(n,e+s))})),this.anchorElement.replaceChildren(t),this.calculate()}goToPage(t){const e=Math.floor(this.state.value.length/this.size);console.log(e),this.currentPage=Math.max(0,Math.min(t,e)),this.renderPage()}nextPage(){this.goToPage(this.currentPage+1)}prevPage(){this.goToPage(this.currentPage-1)}onControl({value:t}){switch(t){case"NEXT":this.nextPage();break;case"PREV":this.prevPage()}}async calculate(){if(this.options.info&&this.options.info.set({current:this.currentPage,size:this.options.size}),this.options.pages){const e=Math.floor(this.state.value.length/this.size);let n=[];for(var t=0;t<e;t++)n.push({isRender:this.currentPage===t,index:t});this.options.pages.set(n)}}async render(){u(this.options.controller,this.onControl.bind(this)),this.options.controller,this.state.reactor.addBinding(this.onStateChange.bind(this)),this.renderPage()}async onStateChange(t){if(!document.contains(this.anchorElement))return d(this.options.controller,this.onControl.bind(this)),void this.state.reactor.removeBinding(this.onStateChange.bind(this));const e=this.currentPage*this.size,n=e+this.size;switch(t.type){case"SET":this.currentPage=0,this.renderPage();break;case"SET_BY_KEY":case"REMOVE_BY_KEY":case"INSERT_BY_KEY":(s=t.key)>=e&&s<n&&this.renderPage();break;case"APPEND":const r=this.state.value.length,i=Math.floor((r-1)/this.size);this.currentPage===i&&this.renderPage();break;default:this.renderPage()}var s}}function v(t){return t!==Object(t)}async function E(t,e,n,r){if(e.parentNode)if(v(n))!function(t,e){t.textContent=String(e)}(e,n);else if(n instanceof c&&n.value instanceof Node)!function(t,e,n){let r=t;const i=()=>{if(!document.contains(r))return void e.reactor.removeBinding(i);const t=e.value;t instanceof s&&t.setContext(n),r.parentNode?.replaceChild(t,r),r=t};i(),e.reactor.addBinding(i)}(e,n,r);else if(n instanceof c)!function(t,e){const n=()=>{document.contains(t)?t.textContent=String(e.value):e.reactor.removeBinding(n)};n(),e.reactor.addBinding(n)}(e,n);else if(Array.isArray(n))!function(t,e,n){const s=document.createDocumentFragment();for(const t of e)t instanceof i?n.renderHelper?.(n,t,s):v(t)?s.appendChild(document.createTextNode(String(t))):t instanceof Node&&s.appendChild(t.cloneNode(!0));t.replaceWith(s)}(e,n,r);else if(n instanceof m)n.prepare(e.parentElement,r),n.render(),e.remove();else if(n instanceof HTMLElement)e.replaceWith(n);else if(n instanceof i)!function(t,e,n){const s=document.createDocumentFragment();n.renderHelper?.(n,e,s),t.replaceWith(s)}(e,n,r);else if(n instanceof NodeList||n instanceof HTMLCollection)n.length>0?function(t,e){const n=document.createDocumentFragment();for(const t of Array.from(e))n.appendChild(t.cloneNode(!0));t.replaceWith(n)}(e,n):e.remove();else if(n&&"function"==typeof n.toString)try{e.textContent=n.toString()}catch{e.textContent=""}else e.textContent=""}function y(t){return new i(t)}window.RUMIOUS_JSX={template:y,createElement:function(...t){throw console.log(t),Error("Rumious doesn't use createElement !")},addDirective:function(t,e,n,s="",r){let i=g[n];if(!i)throw Error("Rumious: Cannot solve directive !");i(e,t,s,r)},dynamicValue:function(t,e,n,s){E(0,e,n,s)},createComponent:function(t){let e=t.tagName;return window.customElements.get(e)||window.customElements.define(e,class extends s{static tag=e}),document.createElement(e)}};class C extends c{constructor(t,e){super(t,e)}set(t,e){if("number"==typeof t&&void 0!==e){const n=t,s=e;this.value[n]=s,this.reactor.emit({type:"SET_BY_KEY",value:s,target:this,key:n})}else{if(!Array.isArray(t))throw new Error("Invalid arguments passed to set()");super.set(t)}}get(t){return"number"==typeof t?this.value[t]:this.value}insert(t,e){return this.value.splice(t,0,e),this.reactor.emit({type:"INSERT_BY_KEY",value:e,target:this,key:t}),this}remove(t){return this.value.splice(t,1),this.reactor.emit({type:"REMOVE_BY_KEY",value:null,target:this,key:t}),this}append(...t){return this.value.push(...t),this.reactor.emit({type:"APPEND",value:t,target:this}),this}prepend(t){return this.value.unshift(t),this.reactor.emit({type:"PREPEND",value:t,target:this}),this}clear(){return this.value.length=0,this.reactor.emit({type:"SET",value:null,target:this}),this}replace(t,e){if(t<0||t>=this.value.length)throw new Error("Index out of bounds");return this.value[t]=e,this.reactor.emit({type:"SET_BY_KEY",value:e,target:this,key:t}),this}filter(t){return this.value=this.value.filter(t),this.reactor.emit({type:"SET",value:null,target:this}),this}map(t){return this.value=this.value.map(t),this.reactor.emit({type:"SET",value:null,target:this}),this}sort(t){return this.value.sort(t),this.reactor.emit({type:"SET",value:null,target:this}),this}reverse(){return this.value.reverse(),this.reactor.emit({type:"SET",value:null,target:this}),this}get length(){return this.value.length}forEach(t){this.value.forEach(t)}}class S extends c{#t=!1;constructor(t,e){super(t,e)}set(t,e){if(this.#t)throw new Error("Object is locked");if("string"==typeof t){const n=t,s=e;return this.value[n]=s,this.reactor.emit({type:"SET_BY_KEY",value:s,target:this,key:n}),this}if("object"!=typeof t)throw new Error("Invalid arguments passed to set()");super.set(t)}remove(t){if(this.#t)throw new Error("Object is locked");return t in this.value&&(delete this.value[t],this.reactor.emit({type:"REMOVE_BY_KEY",value:{...this.value},target:this,key:t})),this}merge(t){if(this.#t)throw new Error("Object is locked");return Object.assign(this.value,t),this.reactor.emit({type:"SET",value:{...this.value},target:this}),this}assign(t){if(this.#t)throw new Error("Object is locked");return this.value={...this.value,...t},this.reactor.emit({type:"SET",value:{...this.value},target:this}),this}clear(){if(this.#t)throw new Error("Object is locked");for(const t in this.value)delete this.value[t];return this.reactor.emit({type:"SET",value:{},target:this}),this}get(t){return"string"==typeof t?this.value[t]:this.value}keys(){return Object.keys(this.value)}values(){return Object.values(this.value)}entries(){return Object.entries(this.value)}has(t){return t in this.value}get size(){return Object.keys(this.value).length}forEach(t){Object.entries(this.value).forEach((([e,n])=>{t(n,e,this.value)}))}map(t){const e={};return Object.entries(this.value).forEach((([n,s])=>{e[n]=t(s,n,this.value)})),e}clone(){return JSON.parse(JSON.stringify(this.value))}toJSON(){return JSON.parse(JSON.stringify(this.value))}toObject(){return this.get()}lock(){return this.#t=!0,this}unlock(){return this.#t=!1,this}get isLocked(){return this.#t}freeze(){return Object.freeze(this.value),this}unfreeze(){return this.value=JSON.parse(JSON.stringify(this.value)),this}get isFrozen(){return Object.isFrozen(this.value)}}window.RUMIOUS_CONTEXTS={};class w{constructor(t={}){this.events={},this.values=t}has(t){return t in this.values}set(t,e){this.values[t]=e}get(t){return this.values[t]}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){this.events[t]&&(this.events[t]=this.events[t].filter((t=>t!==e)))}emit(t,e){this.events[t]&&this.events[t].forEach((t=>t(e)))}}exports.Fragment=function(...t){throw Error("Fragment element must be compiled by Rumious !")},exports.RumiousApp=r,exports.RumiousArrayState=C,exports.RumiousChildrenRef=class{constructor(t){this.target=t}list(){return Array.from(this.target.children)}getChild(t){return this.list()[t]}remove(t){this.list()[t]?.remove()}add(t){this.target.appendChild(t)}querySelector(t){return this.target.querySelector(t)}querySelectorAll(t){return this.target.querySelectorAll(t)}clear(){this.target.innerHTML=""}replaceChild(t,e){const n=this.getChild(t);n&&this.target.replaceChild(e,n)}insertBefore(t,e){const n=this.getChild(e);n?this.target.insertBefore(t,n):this.add(t)}prepend(t){this.target.prepend(t)}getFirstChild(){return this.list()[0]}getLastChild(){return this.list()[this.list().length-1]}hasChildren(){return this.target.hasChildNodes()}count(){return this.target.children.length}find(t){return this.list().find(t)}forEach(t){this.list().forEach(t)}removeAllMatching(t){this.querySelectorAll(t).forEach((t=>t.remove()))}toggleClass(t){this.list().forEach((e=>e.classList.toggle(t)))}setAttribute(t,e){this.list().forEach((n=>n.setAttribute(t,e)))}},exports.RumiousComponent=class{static classNames="";static tagName="rumious-component";constructor(){this.renderOptions={mode:"idle"}}render(t){let e=document.createDocumentFragment();return n(this.context,t,e),e}onCreate(){}onRender(){}onDestroy(){}async onBeforeRender(){}prepare(t,n){this.props=n,this.context=new e(this,t.app)}async requestRender(){await this.onBeforeRender();let t=this.template();n(this.context,t,this.element),this.onRender()}requestCleanup(){}},exports.RumiousComponentElement=s,exports.RumiousContext=w,exports.RumiousDymanicInjector=o,exports.RumiousElementRef=a,exports.RumiousModule=class{},exports.RumiousObjectState=S,exports.RumiousRenderTemplate=i,exports.RumiousState=c,exports.createApp=function(t,e){return new r(t,e)},exports.createArrayState=function(t){return new C(t)},exports.createContext=function(t,e=function(t="_"){return`${t}${(Math.floor(9999*Math.random())*Date.now()).toString(32)}`}("rctx_")){if(window.RUMIOUS_CONTEXTS[e])return window.RUMIOUS_CONTEXTS[e];{let n=new w(t);return window.RUMIOUS_CONTEXTS[e]=n,n}},exports.createElementRef=function(){return new a(document.createElement("span"))},exports.createHTMLInjector=function(t){return new o([t])},exports.createInfinityScroll=function(t){return new p(t)},exports.createObjectState=function(t){return new S(t)},exports.createPagination=function(t){return new f(t)},exports.createState=function(t){return new c(t)},exports.denounce=function(t,e){let n;return function(...s){clearTimeout(n),n=setTimeout((()=>t.apply(this,s)),e)}},exports.leadingTrailingDebounce=function(t,e){let n,s=!0;return function(...r){s&&(t.apply(this,r),s=!1),clearTimeout(n),n=setTimeout((()=>{t.apply(this,r),s=!0}),e)}},exports.rafThrottle=function(t){let e=!1;return function(...n){e||(e=!0,requestAnimationFrame((()=>{t.apply(this,n),e=!1})))}},exports.renderComponent=function(t,e){let n=window.RUMIOUS_JSX.createComponent(t);return n.props=e,n.setComponent(t),n},exports.renderList=function(t,e){return new m(t,e)},exports.template=y,exports.tholle=function(t,e){let n=0;return function(...s){const r=Date.now();r-n>=e&&(n=r,t.apply(this,s))}},exports.trailingThrottle=function(t,e){let n=0,s=null,r=null;function i(){n=Date.now(),t.apply(this,s),s=null}return function(...t){const o=Date.now();s=t,o-n>=e?i.call(this):r||(r=setTimeout((()=>{r=null,i.call(this)}),e-(o-n)))}},exports.unwatch=d,exports.watch=u;
|
package/dist/index.esm.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
import{create as t}from"mutative";class e{constructor(t,e){this.target=t,this.app=e,this.onRenderFinished=[]}findName(t){return this.target[t]}}function n(t,e,s){let i=e.generator.bind(t.target);t.renderHelper=n,i(s,t),setTimeout((async()=>{const e=[...t.onRenderFinished];t.onRenderFinished=[];for(const t of e)await t()}),0)}class s{static classNames="";static tagName="rumious-component";constructor(){this.renderOptions={mode:"idle"}}render(t){let e=document.createDocumentFragment();return n(this.context,t,e),e}onCreate(){}onRender(){}onDestroy(){}async onBeforeRender(){}prepare(t,n){this.props=n,this.context=new e(this,t.app)}async requestRender(){await this.onBeforeRender();let t=this.template();n(this.context,t,this.element),this.onRender()}requestCleanup(){}}class i extends HTMLElement{constructor(){super(),this.props={}}setContext(t){this.context=t}setComponent(t){this.componentConstructor=t}setup(t,e){this.context=t,this.componentConstructor=e}connectedCallback(){this.componentConstructor?(this.componentInstance=new this.componentConstructor,this.componentInstance.element=this,this.componentConstructor.classNames&&(this.className=this.componentConstructor.classNames),this.componentInstance.prepare(this.context,this.props),this.componentInstance.onCreate(),this.componentInstance.requestRender()):console.warn("Rumious: Cannot find matching component constructor.")}disconnectedCallback(){this.componentInstance?.onDestroy()}}function r(t,e){let n=window.RUMIOUS_JSX.createComponent(t);return n.props=e,n.setComponent(t),n}class o{constructor(t,n={}){this.root=t,this.options=n,this.modules=[],this.context=new e(this,this)}addModule(t,e){const n=t.init(this,e);return this.modules.push(n),n}render(t){n(this.context,t,this.root)}}function a(t,e){return new o(t,e)}class h{}class l{constructor(t){this.generator=t}}class c{constructor(t){if(this.contents=t,this.targets=new Map,!t||0===t.length)throw new Error("Injector must be initialized with non-empty content");const e=t[0];this.type="string"==typeof e?"string":"element"}commit(t){this.contents=t;const e=t[0];this.type="string"==typeof e?"string":"element"}addTarget(t){this.targets.set(t,1)}inject(t){if(this.targets.has(t)&&this.contents)if(t.innerHTML="","string"===this.type)for(const e of this.contents)t.insertAdjacentHTML("beforeend",e);else for(const e of this.contents)t.appendChild(e)}injectAll(){for(const t of this.targets.keys())this.inject(t)}removeTarget(t){this.targets.delete(t)}clear(){this.targets.clear()}}function u(t){return new c([t])}class d{constructor(t){this.target=t}getElement(){return this.target}remove(){this.target.remove()}addChild(t){this.target.appendChild(t)}listChild(){return this.target.childNodes}querySelector(t){return this.target.querySelector(t)}querySelectorAll(t){return this.target.querySelectorAll(t)}set text(t){this.target.textContent=t}get text(){return this.target.textContent}set value(t){(this.target instanceof HTMLInputElement||this.target instanceof HTMLTextAreaElement)&&(this.target.value=t)}get value(){if(this.target instanceof HTMLInputElement||this.target instanceof HTMLTextAreaElement)return this.target.value}addClassName(t){this.target.classList.add(t)}removeClassName(t){this.target.classList.remove(t)}hasClassName(t){return this.target.classList.contains(t)}toggleClass(t,e){return this.target.classList.toggle(t,e)}setStyle(t){Object.assign(this.target.style,t)}getStyle(t){return getComputedStyle(this.target).getPropertyValue(t)}setAttribute(t,e){this.target.setAttribute(t,e)}getAttribute(t){return this.target.getAttribute(t)}removeAttribute(t){this.target.removeAttribute(t)}on(t,e,n){this.target.addEventListener(t,e,n)}off(t,e,n){this.target.removeEventListener(t,e,n)}set html(t){this.target.innerHTML=t}get html(){return this.target.innerHTML}getBoundingRect(){return this.target.getBoundingClientRect()}isInViewport(){const t=this.target.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}prependChild(t){this.target.prepend(t)}setDisabled(t){(this.target instanceof HTMLButtonElement||this.target instanceof HTMLInputElement||this.target instanceof HTMLTextAreaElement)&&(this.target.disabled=t)}addClasses(...t){this.target.classList.add(...t)}removeClasses(...t){this.target.classList.remove(...t)}replaceClass(t,e){this.target.classList.replace(t,e)}moveTo(t){t.appendChild(this.target)}getParent(){return this.target.parentElement}getNextSibling(){return this.target.nextElementSibling}getPreviousSibling(){return this.target.previousElementSibling}hide(){this.target.style.display="none"}show(){this.target.style.removeProperty("display")}isHidden(){return"none"===window.getComputedStyle(this.target).display}scrollIntoView(t={behavior:"smooth"}){this.target.scrollIntoView(t)}matches(t){return this.target.matches(t)}getChildren(){return Array.from(this.target.children)}insertAfter(t){this.target.parentNode&&this.target.parentNode.insertBefore(t,this.target.nextSibling)}insertBefore(t){this.target.parentNode&&this.target.parentNode.insertBefore(t,this.target)}clearChildren(){for(;this.target.firstChild;)this.target.removeChild(this.target.firstChild)}animate(t,e){return this.target.animate(t,e)}}function g(){return new d(document.createElement("span"))}function m(t){const e=t.indexOf("$");return-1!==e?t.slice(e+1):""}class p{constructor(t){this.target=t,this.bindings=[]}addBinding(t){this.bindings.push(t)}removeBinding(t){this.bindings=this.bindings.filter((e=>e!==t))}async emit(t){await Promise.allSettled(this.bindings.map((e=>{try{const n=e(t);return n instanceof Promise?n:Promise.resolve(n)}catch(t){return Promise.reject(t)}})))}}class f{constructor(t,e){this.value=t,this.reactor=e??new p(this)}set(t){this.value=t,this.reactor.emit({type:"SET",target:this,value:t})}get(){return this.value}increase(t=1){"number"==typeof this.value&&this.set(this.value+t)}produce(e){const[n,s]=t(this.value);e(n),this.set(s())}}function v(t,e){t.reactor.addBinding(e)}function E(t,e){t.reactor.removeBinding(e)}function y(t){return new f(t)}const C={on:function(t,e,n,s){"string"==typeof s&&(s=t.findName(m(s))),e.addEventListener(n,s)},ref:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(m(s))),!(s instanceof d))throw Error("Rumious: ref directive required RumiousElementRef !");s.target=e},inject:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(m(s))),!(s instanceof c))throw Error("Rumious: inject directive required RumiousInjector !");s.addTarget(e),s.inject(e)},bind:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(m(s))),!(s instanceof f))throw Error("Rumious: bind directive requires RumiousState!");{const t={text:(t,e)=>e.textContent=t,html:(t,e)=>e.innerHTML=t,value:(t,e)=>e.value=t,class:(t,e)=>e.className=t,style:(t,e)=>e.style.cssText=t,checked:(t,e)=>e.checked=t,disabled:(t,e)=>{"disabled"in e&&(e.disabled=t)},readonly:(t,e)=>e.readOnly=t,required:(t,e)=>e.required=t,selected:(t,e)=>e.selected=t,src:(t,e)=>e.src=t,href:(t,e)=>e.href=t,placeholder:(t,e)=>e.placeholder=t,title:(t,e)=>e.title=t,show:(t,e)=>e.style.display=t?"":"none",hide:(t,e)=>e.style.display=t?"none":""}[n]??((t,e)=>e.setAttribute(n,t));t(s.value,e),s.reactor.addBinding((()=>t(s.value,e)))}},model:function(t,e,n,s){if("string"==typeof s&&(s=t.findName(m(s))),!(s instanceof f&&(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)))throw Error("Rumious: model directive requires RumiousState and a valid form element!");{const t=e.type;e.addEventListener("input",(()=>{if(e instanceof HTMLInputElement)switch(t){case"checkbox":s.set(e.checked);break;case"radio":e.checked&&s.set(e.value);break;default:s.set(e.value)}else(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&s.set(e.value)}))}}};class w{constructor(t,e){this.state=t,this.callback=e}prepare(t,e){this.anchorElement=t,this.context=e}renderItem(t,e){const n=document.createDocumentFragment(),s=this.callback(t,e);return this.context.renderHelper(this.context,s,n),n}scheduleRenderAll(){requestAnimationFrame((()=>this.renderAll()))}async render(){this.state.reactor.addBinding(this.onStateChange.bind(this)),this.scheduleRenderAll()}renderAll(){const t=document.createDocumentFragment();this.state.value.forEach(((e,n)=>{t.appendChild(this.renderItem(e,n))})),this.anchorElement.replaceChildren(t)}updateElement(t,e){const n=this.anchorElement.children[t];n&&this.anchorElement.replaceChild(this.renderItem(e,t),n)}insertOrAppendElement(t,e){const n=this.renderItem(t,e),s=this.anchorElement.children[e];s?this.anchorElement.insertBefore(n,s):this.anchorElement.appendChild(n)}removeElement(t){this.anchorElement.children[t]?.remove()}appendElement(t,e){if(Array.isArray(t)){const n=document.createDocumentFragment();t.forEach(((t,s)=>{n.appendChild(this.renderItem(t,e+s))})),this.anchorElement.replaceChildren(n),this.anchorElement.appendChild(n)}}async onStateChange(t){if(document.contains(this.anchorElement))switch(t.type){case"SET":default:this.scheduleRenderAll();break;case"SET_BY_KEY":this.updateElement(t.key,t.value);break;case"REMOVE_BY_KEY":this.removeElement(t.key);break;case"INSERT_BY_KEY":this.insertOrAppendElement(t.value,t.key);break;case"APPEND":this.appendElement(t.value,this.state.value.length-t.value.length);break;case"PREPEND":this.anchorElement.prepend(this.renderItem(t.value,0))}else this.state.reactor.removeBinding(this.onStateChange.bind(this))}}function S(t,e){return new w(t,e)}class b extends w{isLoading=!1;constructor(t){super(t.data,t.template),this.options=t,this.limit=t.limit??50,this.offset=t.offset??0,this.onScroll=this.handleScroll.bind(this),this.onControl=this.handleControl.bind(this),this.onChange=this.handleStateChange.bind(this)}setState(t){this.options.state?.set(t)}async fetchData(){const t=await(this.options.loader?.(this.limit,this.offset))??[];return this.offset+=t.length,t}getScrollInfo(){const t=this.options.scrollElement;return t===window?{scrollTop:window.scrollY,scrollHeight:document.documentElement.scrollHeight,clientHeight:window.innerHeight}:{scrollTop:t.scrollTop,scrollHeight:t.scrollHeight,clientHeight:t.clientHeight}}async addData(){const t=this.options.scrollElement;this.isLoading=!0,this.setState("START_FETCH");const e=await this.fetchData();this.setState("END_FETCH"),0===e.length?(this.setState("NO_DATA"),t.removeEventListener("scroll",this.onScroll)):this.state.append(...e),this.isLoading=!1}async handleScroll(){const{scrollTop:t,scrollHeight:e,clientHeight:n}=this.getScrollInfo();t+n>=e-this.options.threshold&&!this.isLoading&&await this.addData()}handleControl(){"FETCH"===this.options?.controller?.get()&&this.addData()}handleStateChange(t){if(!document.contains(this.anchorElement))return this.options.controller&&E(this.options.controller,this.onControl),void this.state.reactor.removeBinding(this.onChange);this.onStateChange(t)}async render(){this.options.scrollElement.addEventListener("scroll",this.onScroll),this.options.controller&&v(this.options.controller,this.onControl),this.state.reactor.addBinding(this.onChange),this.scheduleRenderAll()}}function T(t){return new b(t)}class N extends w{constructor(t){super(t.data,t.template),this.options=t,this.size=t.size,this.currentPage=t.page??0}getPageData(){const t=this.currentPage*this.size,e=t+this.size;return this.state.value.slice(t,e)}renderPage(){const t=document.createDocumentFragment(),e=this.currentPage*this.size,n=e+this.size;this.state.value.slice(e,n).forEach(((n,s)=>{t.appendChild(this.renderItem(n,e+s))})),this.anchorElement.replaceChildren(t),this.calculate()}goToPage(t){const e=Math.floor(this.state.value.length/this.size);console.log(e),this.currentPage=Math.max(0,Math.min(t,e)),this.renderPage()}nextPage(){this.goToPage(this.currentPage+1)}prevPage(){this.goToPage(this.currentPage-1)}onControl({value:t}){switch(t){case"NEXT":this.nextPage();break;case"PREV":this.prevPage()}}async calculate(){if(this.options.info&&this.options.info.set({current:this.currentPage,size:this.options.size}),this.options.pages){const e=Math.floor(this.state.value.length/this.size);let n=[];for(var t=0;t<e;t++)n.push({isRender:this.currentPage===t,index:t});this.options.pages.set(n)}}async render(){v(this.options.controller,this.onControl.bind(this)),this.options.controller,this.state.reactor.addBinding(this.onStateChange.bind(this)),this.renderPage()}async onStateChange(t){if(!document.contains(this.anchorElement))return E(this.options.controller,this.onControl.bind(this)),void this.state.reactor.removeBinding(this.onStateChange.bind(this));const e=this.currentPage*this.size,n=e+this.size;switch(t.type){case"SET":this.currentPage=0,this.renderPage();break;case"SET_BY_KEY":case"REMOVE_BY_KEY":case"INSERT_BY_KEY":(s=t.key)>=e&&s<n&&this.renderPage();break;case"APPEND":const i=this.state.value.length,r=Math.floor((i-1)/this.size);this.currentPage===r&&this.renderPage();break;default:this.renderPage()}var s}}function k(t){return new N(t)}function x(t){return t!==Object(t)}async function A(t,e,n,s){if(e.parentNode)if(x(n))!function(t,e){t.textContent=String(e)}(e,n);else if(n instanceof f&&n.value instanceof Node)!function(t,e,n){let s=t;const r=()=>{if(!document.contains(s))return void e.reactor.removeBinding(r);const t=e.value;t instanceof i&&t.setContext(n),s.parentNode?.replaceChild(t,s),s=t};r(),e.reactor.addBinding(r)}(e,n,s);else if(n instanceof f)!function(t,e){const n=()=>{document.contains(t)?t.textContent=String(e.value):e.reactor.removeBinding(n)};n(),e.reactor.addBinding(n)}(e,n);else if(Array.isArray(n))!function(t,e,n){const s=document.createDocumentFragment();for(const t of e)t instanceof l?n.renderHelper?.(n,t,s):x(t)?s.appendChild(document.createTextNode(String(t))):t instanceof Node&&s.appendChild(t.cloneNode(!0));t.replaceWith(s)}(e,n,s);else if(n instanceof w)n.prepare(e.parentElement,s),n.render(),e.remove();else if(n instanceof HTMLElement)e.replaceWith(n);else if(n instanceof l)!function(t,e,n){const s=document.createDocumentFragment();n.renderHelper?.(n,e,s),t.replaceWith(s)}(e,n,s);else if(n instanceof NodeList||n instanceof HTMLCollection)n.length>0?function(t,e){const n=document.createDocumentFragment();for(const t of Array.from(e))n.appendChild(t.cloneNode(!0));t.replaceWith(n)}(e,n):e.remove();else if(n&&"function"==typeof n.toString)try{e.textContent=n.toString()}catch{e.textContent=""}else e.textContent=""}function R(t){return new l(t)}const P=function(...t){throw Error("Fragment element must be compiled by Rumious !")};window.RUMIOUS_JSX={template:R,createElement:function(...t){throw console.log(t),Error("Rumious doesn't use createElement !")},addDirective:function(t,e,n,s="",i){let r=C[n];if(!r)throw Error("Rumious: Cannot solve directive !");r(e,t,s,i)},dynamicValue:function(t,e,n,s){A(0,e,n,s)},createComponent:function(t){let e=t.tagName;return window.customElements.get(e)||window.customElements.define(e,class extends i{static tag=e}),document.createElement(e)}};class O{constructor(t){this.target=t}list(){return Array.from(this.target.children)}getChild(t){return this.list()[t]}remove(t){this.list()[t]?.remove()}add(t){this.target.appendChild(t)}querySelector(t){return this.target.querySelector(t)}querySelectorAll(t){return this.target.querySelectorAll(t)}clear(){this.target.innerHTML=""}replaceChild(t,e){const n=this.getChild(t);n&&this.target.replaceChild(e,n)}insertBefore(t,e){const n=this.getChild(e);n?this.target.insertBefore(t,n):this.add(t)}prepend(t){this.target.prepend(t)}getFirstChild(){return this.list()[0]}getLastChild(){return this.list()[this.list().length-1]}hasChildren(){return this.target.hasChildNodes()}count(){return this.target.children.length}find(t){return this.list().find(t)}forEach(t){this.list().forEach(t)}removeAllMatching(t){this.querySelectorAll(t).forEach((t=>t.remove()))}toggleClass(t){this.list().forEach((e=>e.classList.toggle(t)))}setAttribute(t,e){this.list().forEach((n=>n.setAttribute(t,e)))}}class L extends f{constructor(t,e){super(t,e)}set(t,e){if("number"==typeof t&&void 0!==e){const n=t,s=e;this.value[n]=s,this.reactor.emit({type:"SET_BY_KEY",value:s,target:this,key:n})}else{if(!Array.isArray(t))throw new Error("Invalid arguments passed to set()");super.set(t)}}get(t){return"number"==typeof t?this.value[t]:this.value}insert(t,e){return this.value.splice(t,0,e),this.reactor.emit({type:"INSERT_BY_KEY",value:e,target:this,key:t}),this}remove(t){return this.value.splice(t,1),this.reactor.emit({type:"REMOVE_BY_KEY",value:null,target:this,key:t}),this}append(...t){return this.value.push(...t),this.reactor.emit({type:"APPEND",value:t,target:this}),this}prepend(t){return this.value.unshift(t),this.reactor.emit({type:"PREPEND",value:t,target:this}),this}clear(){return this.value.length=0,this.reactor.emit({type:"SET",value:null,target:this}),this}replace(t,e){if(t<0||t>=this.value.length)throw new Error("Index out of bounds");return this.value[t]=e,this.reactor.emit({type:"SET_BY_KEY",value:e,target:this,key:t}),this}filter(t){return this.value=this.value.filter(t),this.reactor.emit({type:"SET",value:null,target:this}),this}map(t){return this.value=this.value.map(t),this.reactor.emit({type:"SET",value:null,target:this}),this}sort(t){return this.value.sort(t),this.reactor.emit({type:"SET",value:null,target:this}),this}reverse(){return this.value.reverse(),this.reactor.emit({type:"SET",value:null,target:this}),this}get length(){return this.value.length}forEach(t){this.value.forEach(t)}}function H(t){return new L(t)}class M extends f{#t=!1;constructor(t,e){super(t,e)}set(t,e){if(this.#t)throw new Error("Object is locked");if("string"==typeof t){const n=t,s=e;return this.value[n]=s,this.reactor.emit({type:"SET_BY_KEY",value:s,target:this,key:n}),this}if("object"!=typeof t)throw new Error("Invalid arguments passed to set()");super.set(t)}remove(t){if(this.#t)throw new Error("Object is locked");return t in this.value&&(delete this.value[t],this.reactor.emit({type:"REMOVE_BY_KEY",value:{...this.value},target:this,key:t})),this}merge(t){if(this.#t)throw new Error("Object is locked");return Object.assign(this.value,t),this.reactor.emit({type:"SET",value:{...this.value},target:this}),this}assign(t){if(this.#t)throw new Error("Object is locked");return this.value={...this.value,...t},this.reactor.emit({type:"SET",value:{...this.value},target:this}),this}clear(){if(this.#t)throw new Error("Object is locked");for(const t in this.value)delete this.value[t];return this.reactor.emit({type:"SET",value:{},target:this}),this}get(t){return"string"==typeof t?this.value[t]:this.value}keys(){return Object.keys(this.value)}values(){return Object.values(this.value)}entries(){return Object.entries(this.value)}has(t){return t in this.value}get size(){return Object.keys(this.value).length}forEach(t){Object.entries(this.value).forEach((([e,n])=>{t(n,e,this.value)}))}map(t){const e={};return Object.entries(this.value).forEach((([n,s])=>{e[n]=t(s,n,this.value)})),e}clone(){return JSON.parse(JSON.stringify(this.value))}toJSON(){return JSON.parse(JSON.stringify(this.value))}toObject(){return this.get()}lock(){return this.#t=!0,this}unlock(){return this.#t=!1,this}get isLocked(){return this.#t}freeze(){return Object.freeze(this.value),this}unfreeze(){return this.value=JSON.parse(JSON.stringify(this.value)),this}get isFrozen(){return Object.isFrozen(this.value)}}function B(t){return new M(t)}window.RUMIOUS_CONTEXTS={};class I{constructor(t={}){this.events={},this.values=t}has(t){return t in this.values}set(t,e){this.values[t]=e}get(t){return this.values[t]}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){this.events[t]&&(this.events[t]=this.events[t].filter((t=>t!==e)))}emit(t,e){this.events[t]&&this.events[t].forEach((t=>t(e)))}}function _(t,e=function(t="_"){return`${t}${(Math.floor(9999*Math.random())*Date.now()).toString(32)}`}("rctx_")){if(window.RUMIOUS_CONTEXTS[e])return window.RUMIOUS_CONTEXTS[e];{let n=new I(t);return window.RUMIOUS_CONTEXTS[e]=n,n}}function D(t,e){let n=0;return function(...s){const i=Date.now();i-n>=e&&(n=i,t.apply(this,s))}}function j(t,e){let n;return function(...s){clearTimeout(n),n=setTimeout((()=>t.apply(this,s)),e)}}function Y(t,e){let n=0,s=null,i=null;function r(){n=Date.now(),t.apply(this,s),s=null}return function(...t){const o=Date.now();s=t,o-n>=e?r.call(this):i||(i=setTimeout((()=>{i=null,r.call(this)}),e-(o-n)))}}function q(t,e){let n,s=!0;return function(...i){s&&(t.apply(this,i),s=!1),clearTimeout(n),n=setTimeout((()=>{t.apply(this,i),s=!0}),e)}}function z(t){let e=!1;return function(...n){e||(e=!0,requestAnimationFrame((()=>{t.apply(this,n),e=!1})))}}export{P as Fragment,o as RumiousApp,L as RumiousArrayState,O as RumiousChildrenRef,s as RumiousComponent,i as RumiousComponentElement,I as RumiousContext,c as RumiousDymanicInjector,d as RumiousElementRef,h as RumiousModule,M as RumiousObjectState,l as RumiousRenderTemplate,f as RumiousState,a as createApp,H as createArrayState,_ as createContext,g as createElementRef,u as createHTMLInjector,T as createInfinityScroll,B as createObjectState,k as createPagination,y as createState,j as denounce,q as leadingTrailingDebounce,z as rafThrottle,r as renderComponent,S as renderList,R as template,D as tholle,Y as trailingThrottle,E as unwatch,v as watch};
|
package/dist/index.global.d.ts
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
import * as Component from './component/index.js';
|
2
|
-
import * as App from './app/index.js';
|
3
|
-
import * as Render from './render/index.js';
|
4
|
-
import * as Ref from './ref/index.js';
|
5
|
-
import * as State from './state/index.js';
|
6
|
-
import * as Context from './context/index.js';
|
7
|
-
declare global {
|
8
|
-
interface Window {
|
9
|
-
Rumious: Record<string, any>;
|
10
|
-
}
|
11
|
-
}
|
12
|
-
declare const Rumious: {
|
13
|
-
tholle<T extends (...args: any[]) => any>(func: T, limit: number): T;
|
14
|
-
denounce<T extends (...args: any[]) => any>(func: T, delay: number): T;
|
15
|
-
trailingThrottle<T extends (...args: any[]) => any>(func: T, limit: number): T;
|
16
|
-
leadingTrailingDebounce<T extends (...args: any[]) => any>(func: T, delay: number): T;
|
17
|
-
rafThrottle<T extends (...args: any[]) => any>(func: T): T;
|
18
|
-
createContext<T extends object>(values: T, name?: string): Context.RumiousContext<T>;
|
19
|
-
RumiousContext: typeof Context.RumiousContext;
|
20
|
-
watch<T>(state: State.RumiousState<T>, fn: import("./state/reactor.js").RumiousBinding<T>): void;
|
21
|
-
unwatch<T>(state: State.RumiousState<T>, fn: import("./state/reactor.js").RumiousBinding<T>): void;
|
22
|
-
createState<T>(value: T): State.RumiousState<T>;
|
23
|
-
RumiousState: typeof State.RumiousState;
|
24
|
-
createArrayState<T>(value: T[]): State.RumiousArrayState<T>;
|
25
|
-
RumiousArrayState: typeof State.RumiousArrayState;
|
26
|
-
createObjectState<T extends Record<string, any>>(value: T): State.RumiousObjectState<T>;
|
27
|
-
RumiousObjectState: typeof State.RumiousObjectState;
|
28
|
-
createElementRef(): Ref.RumiousElementRef;
|
29
|
-
RumiousElementRef: typeof Ref.RumiousElementRef;
|
30
|
-
RumiousChildrenRef: typeof Ref.RumiousChildrenRef;
|
31
|
-
renderList: typeof Render.renderList;
|
32
|
-
createInfinityScroll: typeof Render.createInfinityScroll;
|
33
|
-
createPagination: typeof Render.createPagination;
|
34
|
-
RumiousRenderTemplate: typeof Render.RumiousRenderTemplate;
|
35
|
-
createHTMLInjector(html: string): Render.RumiousDymanicInjector<string>;
|
36
|
-
RumiousDymanicInjector: typeof Render.RumiousDymanicInjector;
|
37
|
-
template(generator: import("./types/render.js").RumiousTemplateGenerator): Render.RumiousRenderTemplate;
|
38
|
-
Fragment: (...args: any[]) => any;
|
39
|
-
createApp(root: HTMLElement, options?: App.RumiousAppOptions): App.RumiousApp;
|
40
|
-
RumiousApp: typeof App.RumiousApp;
|
41
|
-
RumiousModule: typeof App.RumiousModule;
|
42
|
-
RumiousComponent: typeof Component.RumiousComponent;
|
43
|
-
renderComponent(component: Component.RumiousComponentConstructor, props: any): HTMLElement;
|
44
|
-
RumiousComponentElement: typeof Component.RumiousComponentElement;
|
45
|
-
};
|
46
|
-
export default Rumious;
|