rask-ui 0.2.5 → 0.2.7
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/vdom/AbstractVNode.d.ts +20 -1
- package/dist/vdom/AbstractVNode.d.ts.map +1 -1
- package/dist/vdom/AbstractVNode.js +151 -12
- package/dist/vdom/ComponentVNode.d.ts +2 -2
- package/dist/vdom/ComponentVNode.d.ts.map +1 -1
- package/dist/vdom/ComponentVNode.js +17 -8
- package/dist/vdom/ElementVNode.d.ts +6 -9
- package/dist/vdom/ElementVNode.d.ts.map +1 -1
- package/dist/vdom/ElementVNode.js +103 -34
- package/dist/vdom/FragmentVNode.d.ts +2 -2
- package/dist/vdom/FragmentVNode.d.ts.map +1 -1
- package/dist/vdom/FragmentVNode.js +18 -7
- package/dist/vdom/RootVNode.d.ts +2 -2
- package/dist/vdom/RootVNode.d.ts.map +1 -1
- package/dist/vdom/RootVNode.js +15 -6
- package/dist/vdom/dom-utils.d.ts +6 -1
- package/dist/vdom/dom-utils.d.ts.map +1 -1
- package/dist/vdom/dom-utils.js +20 -1
- package/dist/vdom/types.d.ts +12 -0
- package/dist/vdom/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/component.d.ts +0 -38
- package/dist/component.d.ts.map +0 -1
- package/dist/component.js +0 -130
- package/dist/context.d.ts +0 -5
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -29
- package/dist/createAsync.test.d.ts +0 -2
- package/dist/createAsync.test.d.ts.map +0 -1
- package/dist/createAsync.test.js +0 -110
- package/dist/createAsyncState.d.ts +0 -16
- package/dist/createAsyncState.d.ts.map +0 -1
- package/dist/createAsyncState.js +0 -24
- package/dist/createContext.test.d.ts +0 -2
- package/dist/createContext.test.d.ts.map +0 -1
- package/dist/createContext.test.js +0 -136
- package/dist/createMutation.test.d.ts +0 -2
- package/dist/createMutation.test.d.ts.map +0 -1
- package/dist/createMutation.test.js +0 -168
- package/dist/createQuery.test.d.ts +0 -2
- package/dist/createQuery.test.d.ts.map +0 -1
- package/dist/createQuery.test.js +0 -156
- package/dist/createRef.test.d.ts +0 -2
- package/dist/createRef.test.d.ts.map +0 -1
- package/dist/createRef.test.js +0 -80
- package/dist/createState.test.d.ts +0 -2
- package/dist/createState.test.d.ts.map +0 -1
- package/dist/createState.test.js +0 -111
- package/dist/createView.test.d.ts +0 -2
- package/dist/createView.test.d.ts.map +0 -1
- package/dist/createView.test.js +0 -203
- package/dist/error.test.d.ts +0 -2
- package/dist/error.test.d.ts.map +0 -1
- package/dist/error.test.js +0 -144
- package/dist/integration.test.d.ts +0 -2
- package/dist/integration.test.d.ts.map +0 -1
- package/dist/integration.test.js +0 -155
- package/dist/jsx.d.ts.map +0 -1
- package/dist/jsx.js +0 -42
- package/dist/observation.test.d.ts +0 -2
- package/dist/observation.test.d.ts.map +0 -1
- package/dist/observation.test.js +0 -113
- package/dist/render-test.d.ts +0 -2
- package/dist/render-test.d.ts.map +0 -1
- package/dist/render-test.js +0 -21
- package/dist/render.d.ts +0 -7
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -77
- package/dist/suspense.d.ts +0 -25
- package/dist/suspense.d.ts.map +0 -1
- package/dist/suspense.js +0 -97
- package/dist/tests/class.test.d.ts +0 -2
- package/dist/tests/class.test.d.ts.map +0 -1
- package/dist/tests/class.test.js +0 -185
- package/dist/tests/complex-rendering.test.d.ts +0 -2
- package/dist/tests/complex-rendering.test.d.ts.map +0 -1
- package/dist/tests/complex-rendering.test.js +0 -400
- package/dist/tests/component.cleanup.test.d.ts +0 -2
- package/dist/tests/component.cleanup.test.d.ts.map +0 -1
- package/dist/tests/component.cleanup.test.js +0 -325
- package/dist/tests/component.counter.test.d.ts +0 -2
- package/dist/tests/component.counter.test.d.ts.map +0 -1
- package/dist/tests/component.counter.test.js +0 -124
- package/dist/tests/component.interaction.test.d.ts +0 -2
- package/dist/tests/component.interaction.test.d.ts.map +0 -1
- package/dist/tests/component.interaction.test.js +0 -73
- package/dist/tests/component.props.test.d.ts +0 -2
- package/dist/tests/component.props.test.d.ts.map +0 -1
- package/dist/tests/component.props.test.js +0 -334
- package/dist/tests/component.return-types.test.d.ts +0 -2
- package/dist/tests/component.return-types.test.d.ts.map +0 -1
- package/dist/tests/component.return-types.test.js +0 -357
- package/dist/tests/component.state.test.d.ts +0 -2
- package/dist/tests/component.state.test.d.ts.map +0 -1
- package/dist/tests/component.state.test.js +0 -135
- package/dist/tests/component.test.d.ts +0 -2
- package/dist/tests/component.test.d.ts.map +0 -1
- package/dist/tests/component.test.js +0 -63
- package/dist/tests/createAsync.test.d.ts +0 -2
- package/dist/tests/createAsync.test.d.ts.map +0 -1
- package/dist/tests/createAsync.test.js +0 -110
- package/dist/tests/createContext.test.d.ts +0 -2
- package/dist/tests/createContext.test.d.ts.map +0 -1
- package/dist/tests/createContext.test.js +0 -141
- package/dist/tests/createMutation.test.d.ts +0 -2
- package/dist/tests/createMutation.test.d.ts.map +0 -1
- package/dist/tests/createMutation.test.js +0 -168
- package/dist/tests/createQuery.test.d.ts +0 -2
- package/dist/tests/createQuery.test.d.ts.map +0 -1
- package/dist/tests/createQuery.test.js +0 -156
- package/dist/tests/createRef.test.d.ts +0 -2
- package/dist/tests/createRef.test.d.ts.map +0 -1
- package/dist/tests/createRef.test.js +0 -84
- package/dist/tests/createState.test.d.ts +0 -2
- package/dist/tests/createState.test.d.ts.map +0 -1
- package/dist/tests/createState.test.js +0 -103
- package/dist/tests/createView.test.d.ts +0 -2
- package/dist/tests/createView.test.d.ts.map +0 -1
- package/dist/tests/createView.test.js +0 -203
- package/dist/tests/edge-cases.test.d.ts +0 -2
- package/dist/tests/edge-cases.test.d.ts.map +0 -1
- package/dist/tests/edge-cases.test.js +0 -637
- package/dist/tests/error-no-boundary.test.d.ts +0 -2
- package/dist/tests/error-no-boundary.test.d.ts.map +0 -1
- package/dist/tests/error-no-boundary.test.js +0 -174
- package/dist/tests/error.test.d.ts +0 -2
- package/dist/tests/error.test.d.ts.map +0 -1
- package/dist/tests/error.test.js +0 -199
- package/dist/tests/fragment.test.d.ts +0 -2
- package/dist/tests/fragment.test.d.ts.map +0 -1
- package/dist/tests/fragment.test.js +0 -618
- package/dist/tests/integration.test.d.ts +0 -2
- package/dist/tests/integration.test.d.ts.map +0 -1
- package/dist/tests/integration.test.js +0 -192
- package/dist/tests/keys.test.d.ts +0 -2
- package/dist/tests/keys.test.d.ts.map +0 -1
- package/dist/tests/keys.test.js +0 -293
- package/dist/tests/mount.test.d.ts +0 -2
- package/dist/tests/mount.test.d.ts.map +0 -1
- package/dist/tests/mount.test.js +0 -91
- package/dist/tests/observation.test.d.ts +0 -2
- package/dist/tests/observation.test.d.ts.map +0 -1
- package/dist/tests/observation.test.js +0 -113
- package/dist/tests/patch.test.d.ts +0 -2
- package/dist/tests/patch.test.d.ts.map +0 -1
- package/dist/tests/patch.test.js +0 -498
- package/dist/tests/patchChildren.test.d.ts +0 -2
- package/dist/tests/patchChildren.test.d.ts.map +0 -1
- package/dist/tests/patchChildren.test.js +0 -405
- package/dist/tests/primitives.test.d.ts +0 -2
- package/dist/tests/primitives.test.d.ts.map +0 -1
- package/dist/tests/primitives.test.js +0 -132
- package/dist/vdom/class.test.d.ts +0 -2
- package/dist/vdom/class.test.d.ts.map +0 -1
- package/dist/vdom/class.test.js +0 -143
- package/dist/vdom/complex-rendering.test.d.ts +0 -2
- package/dist/vdom/complex-rendering.test.d.ts.map +0 -1
- package/dist/vdom/complex-rendering.test.js +0 -400
- package/dist/vdom/component.cleanup.test.d.ts +0 -2
- package/dist/vdom/component.cleanup.test.d.ts.map +0 -1
- package/dist/vdom/component.cleanup.test.js +0 -323
- package/dist/vdom/component.counter.test.d.ts +0 -2
- package/dist/vdom/component.counter.test.d.ts.map +0 -1
- package/dist/vdom/component.counter.test.js +0 -124
- package/dist/vdom/component.interaction.test.d.ts +0 -2
- package/dist/vdom/component.interaction.test.d.ts.map +0 -1
- package/dist/vdom/component.interaction.test.js +0 -73
- package/dist/vdom/component.props.test.d.ts +0 -2
- package/dist/vdom/component.props.test.d.ts.map +0 -1
- package/dist/vdom/component.props.test.js +0 -88
- package/dist/vdom/component.return-types.test.d.ts +0 -2
- package/dist/vdom/component.return-types.test.d.ts.map +0 -1
- package/dist/vdom/component.return-types.test.js +0 -357
- package/dist/vdom/component.state.test.d.ts +0 -2
- package/dist/vdom/component.state.test.d.ts.map +0 -1
- package/dist/vdom/component.state.test.js +0 -129
- package/dist/vdom/component.test.d.ts +0 -2
- package/dist/vdom/component.test.d.ts.map +0 -1
- package/dist/vdom/component.test.js +0 -63
- package/dist/vdom/edge-cases.test.d.ts +0 -2
- package/dist/vdom/edge-cases.test.d.ts.map +0 -1
- package/dist/vdom/edge-cases.test.js +0 -637
- package/dist/vdom/fragment.test.d.ts +0 -2
- package/dist/vdom/fragment.test.d.ts.map +0 -1
- package/dist/vdom/fragment.test.js +0 -618
- package/dist/vdom/keys.test.d.ts +0 -2
- package/dist/vdom/keys.test.d.ts.map +0 -1
- package/dist/vdom/keys.test.js +0 -293
- package/dist/vdom/mount.test.d.ts +0 -2
- package/dist/vdom/mount.test.d.ts.map +0 -1
- package/dist/vdom/mount.test.js +0 -91
- package/dist/vdom/patch.test.d.ts +0 -2
- package/dist/vdom/patch.test.d.ts.map +0 -1
- package/dist/vdom/patch.test.js +0 -498
- package/dist/vdom/patchChildren.test.d.ts +0 -2
- package/dist/vdom/patchChildren.test.d.ts.map +0 -1
- package/dist/vdom/patchChildren.test.js +0 -392
- package/dist/vdom/primitives.test.d.ts +0 -2
- package/dist/vdom/primitives.test.d.ts.map +0 -1
- package/dist/vdom/primitives.test.js +0 -132
package/dist/observation.test.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { Signal, Observer, getCurrentObserver } from "./observation";
|
|
3
|
-
describe("Signal", () => {
|
|
4
|
-
it("should allow subscribing to notifications", () => {
|
|
5
|
-
const signal = new Signal();
|
|
6
|
-
const callback = vi.fn();
|
|
7
|
-
signal.subscribe(callback);
|
|
8
|
-
signal.notify();
|
|
9
|
-
expect(callback).toHaveBeenCalledTimes(1);
|
|
10
|
-
});
|
|
11
|
-
it("should return a disposer function", () => {
|
|
12
|
-
const signal = new Signal();
|
|
13
|
-
const callback = vi.fn();
|
|
14
|
-
const dispose = signal.subscribe(callback);
|
|
15
|
-
dispose();
|
|
16
|
-
signal.notify();
|
|
17
|
-
expect(callback).not.toHaveBeenCalled();
|
|
18
|
-
});
|
|
19
|
-
it("should handle multiple subscribers", () => {
|
|
20
|
-
const signal = new Signal();
|
|
21
|
-
const callback1 = vi.fn();
|
|
22
|
-
const callback2 = vi.fn();
|
|
23
|
-
signal.subscribe(callback1);
|
|
24
|
-
signal.subscribe(callback2);
|
|
25
|
-
signal.notify();
|
|
26
|
-
expect(callback1).toHaveBeenCalledTimes(1);
|
|
27
|
-
expect(callback2).toHaveBeenCalledTimes(1);
|
|
28
|
-
});
|
|
29
|
-
it("should allow unsubscribing individual callbacks", () => {
|
|
30
|
-
const signal = new Signal();
|
|
31
|
-
const callback1 = vi.fn();
|
|
32
|
-
const callback2 = vi.fn();
|
|
33
|
-
const dispose1 = signal.subscribe(callback1);
|
|
34
|
-
signal.subscribe(callback2);
|
|
35
|
-
dispose1();
|
|
36
|
-
signal.notify();
|
|
37
|
-
expect(callback1).not.toHaveBeenCalled();
|
|
38
|
-
expect(callback2).toHaveBeenCalledTimes(1);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe("Observer", () => {
|
|
42
|
-
it("should track signals during observation", () => {
|
|
43
|
-
const callback = vi.fn();
|
|
44
|
-
const observer = new Observer(callback);
|
|
45
|
-
const signal = new Signal();
|
|
46
|
-
const dispose = observer.observe();
|
|
47
|
-
observer.subscribeSignal(signal);
|
|
48
|
-
dispose();
|
|
49
|
-
signal.notify();
|
|
50
|
-
return new Promise((resolve) => {
|
|
51
|
-
queueMicrotask(() => {
|
|
52
|
-
expect(callback).toHaveBeenCalledTimes(1);
|
|
53
|
-
resolve(undefined);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
it("should clear signals when observing again", async () => {
|
|
58
|
-
let callCount = 0;
|
|
59
|
-
const observer = new Observer(() => {
|
|
60
|
-
callCount++;
|
|
61
|
-
});
|
|
62
|
-
const signal1 = new Signal();
|
|
63
|
-
const signal2 = new Signal();
|
|
64
|
-
// First observation
|
|
65
|
-
let dispose = observer.observe();
|
|
66
|
-
observer.subscribeSignal(signal1);
|
|
67
|
-
dispose();
|
|
68
|
-
// Second observation - should clear previous signals
|
|
69
|
-
dispose = observer.observe();
|
|
70
|
-
observer.subscribeSignal(signal2);
|
|
71
|
-
dispose();
|
|
72
|
-
// Notify first signal - should not trigger observer
|
|
73
|
-
signal1.notify();
|
|
74
|
-
await new Promise((resolve) => queueMicrotask(() => resolve()));
|
|
75
|
-
expect(callCount).toBe(0);
|
|
76
|
-
// Notify second signal - should trigger observer
|
|
77
|
-
signal2.notify();
|
|
78
|
-
await new Promise((resolve) => queueMicrotask(() => resolve()));
|
|
79
|
-
expect(callCount).toBe(1);
|
|
80
|
-
});
|
|
81
|
-
it("should dispose of all signal subscriptions", async () => {
|
|
82
|
-
const callback = vi.fn();
|
|
83
|
-
const observer = new Observer(callback);
|
|
84
|
-
const signal = new Signal();
|
|
85
|
-
const dispose = observer.observe();
|
|
86
|
-
observer.subscribeSignal(signal);
|
|
87
|
-
dispose();
|
|
88
|
-
observer.dispose();
|
|
89
|
-
signal.notify();
|
|
90
|
-
await new Promise((resolve) => queueMicrotask(() => resolve()));
|
|
91
|
-
expect(callback).not.toHaveBeenCalled();
|
|
92
|
-
});
|
|
93
|
-
it("should set current observer during observation", () => {
|
|
94
|
-
const observer = new Observer(() => {});
|
|
95
|
-
expect(getCurrentObserver()).toBeUndefined();
|
|
96
|
-
const dispose = observer.observe();
|
|
97
|
-
expect(getCurrentObserver()).toBe(observer);
|
|
98
|
-
dispose();
|
|
99
|
-
expect(getCurrentObserver()).toBeUndefined();
|
|
100
|
-
});
|
|
101
|
-
it("should handle nested observations with stack", () => {
|
|
102
|
-
const observer1 = new Observer(() => {});
|
|
103
|
-
const observer2 = new Observer(() => {});
|
|
104
|
-
const dispose1 = observer1.observe();
|
|
105
|
-
expect(getCurrentObserver()).toBe(observer1);
|
|
106
|
-
const dispose2 = observer2.observe();
|
|
107
|
-
expect(getCurrentObserver()).toBe(observer2);
|
|
108
|
-
dispose2();
|
|
109
|
-
expect(getCurrentObserver()).toBe(observer1);
|
|
110
|
-
dispose1();
|
|
111
|
-
expect(getCurrentObserver()).toBeUndefined();
|
|
112
|
-
});
|
|
113
|
-
});
|
package/dist/render-test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"render-test.d.ts","sourceRoot":"","sources":["../src/render-test.ts"],"names":[],"mappings":""}
|
package/dist/render-test.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Quick test to understand Snabbdom's behavior
|
|
2
|
-
import { patch } from './render';
|
|
3
|
-
import { h } from 'snabbdom';
|
|
4
|
-
import { JSDOM } from 'jsdom';
|
|
5
|
-
const dom = new JSDOM('<!DOCTYPE html><html><body><div id="app"></div></body></html>');
|
|
6
|
-
global.window = dom.window;
|
|
7
|
-
global.document = dom.window.document;
|
|
8
|
-
const container = document.getElementById('app');
|
|
9
|
-
const parent = container.parentElement;
|
|
10
|
-
console.log('Before patch:');
|
|
11
|
-
console.log('Container id:', container.id);
|
|
12
|
-
console.log('Parent children:', parent.children.length);
|
|
13
|
-
console.log('Parent innerHTML:', parent.innerHTML);
|
|
14
|
-
const vnode = h('div', { props: { id: 'app' } }, [h('span', {}, 'Hello')]);
|
|
15
|
-
const result = patch(container, vnode);
|
|
16
|
-
console.log('\nAfter patch:');
|
|
17
|
-
console.log('Result:', result);
|
|
18
|
-
console.log('Result.elm:', result.elm);
|
|
19
|
-
console.log('Parent children:', parent.children.length);
|
|
20
|
-
console.log('Parent innerHTML:', parent.innerHTML);
|
|
21
|
-
console.log('Container still in DOM?:', document.getElementById('app'));
|
package/dist/render.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type VNode } from "snabbdom";
|
|
2
|
-
import { type Component } from "./component";
|
|
3
|
-
export declare const patch: (oldVnode: VNode | Element | DocumentFragment, vnode: VNode) => VNode;
|
|
4
|
-
export type ChildNode = VNode | string | null | number;
|
|
5
|
-
export declare function render(vnode: VNode, container: HTMLElement): VNode;
|
|
6
|
-
export declare function jsx(type: string | Component<any>, props: Record<string, unknown>, children: ChildNode[]): VNode;
|
|
7
|
-
//# sourceMappingURL=render.d.ts.map
|
package/dist/render.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,KAAK,EAEX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE9D,eAAO,MAAM,KAAK,uEAOhB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvD,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,SAK1D;AAED,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,EAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,SAAS,EAAE,SAyEtB"}
|
package/dist/render.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { init, classModule, propsModule, styleModule, eventListenersModule, attributesModule, h, } from "snabbdom";
|
|
2
|
-
import { createComponent } from "./component";
|
|
3
|
-
export const patch = init([
|
|
4
|
-
// Init patch function with chosen modules
|
|
5
|
-
classModule, // makes it easy to toggle classes
|
|
6
|
-
propsModule, // for setting properties on DOM elements
|
|
7
|
-
styleModule, // handles styling on elements with support for animations
|
|
8
|
-
eventListenersModule, // attaches event listeners
|
|
9
|
-
attributesModule,
|
|
10
|
-
]);
|
|
11
|
-
export function render(vnode, container) {
|
|
12
|
-
const style = document.createElement("style");
|
|
13
|
-
style.innerHTML = "component { display: contents; }";
|
|
14
|
-
document.head.appendChild(style);
|
|
15
|
-
return patch(container, vnode);
|
|
16
|
-
}
|
|
17
|
-
export function jsx(type, props, children) {
|
|
18
|
-
let flatChildren = children.flat();
|
|
19
|
-
if (typeof type === "string") {
|
|
20
|
-
const data = {};
|
|
21
|
-
for (const key in props) {
|
|
22
|
-
if (key === "key") {
|
|
23
|
-
data[key] = props[key];
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
if (key === "hook") {
|
|
27
|
-
data[key] = props[key];
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (key === "style") {
|
|
31
|
-
data.style = props[key];
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
if (key === "class") {
|
|
35
|
-
// Snabbdom's classModule expects an object like { 'class-name': true }
|
|
36
|
-
// If it's a string, convert it to the object format
|
|
37
|
-
const classValue = props[key];
|
|
38
|
-
if (typeof classValue === 'string') {
|
|
39
|
-
data.class = { [classValue]: true };
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
data.class = classValue;
|
|
43
|
-
}
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
if (key === "ref") {
|
|
47
|
-
data.hook = data.hook || {};
|
|
48
|
-
const existingInsertHook = data.hook?.insert;
|
|
49
|
-
data.hook.insert = (vnode) => {
|
|
50
|
-
existingInsertHook?.(vnode);
|
|
51
|
-
props.ref(vnode.elm || null);
|
|
52
|
-
};
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (key.startsWith("on")) {
|
|
56
|
-
data.on = data.on || {};
|
|
57
|
-
data.on[key.substring(2).toLocaleLowerCase()] = props[key];
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
61
|
-
data.attrs = data.attrs || {};
|
|
62
|
-
data.attrs[key] = props[key];
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (type === "svg") {
|
|
66
|
-
data.attrs = data.attrs || {};
|
|
67
|
-
data.attrs[key] = props[key];
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
data.props = data.props || {};
|
|
71
|
-
data.props[key] = props[key];
|
|
72
|
-
}
|
|
73
|
-
return h(type, data, flatChildren);
|
|
74
|
-
}
|
|
75
|
-
const maybeSingleChild = flatChildren.length === 1 ? flatChildren[0] : flatChildren;
|
|
76
|
-
return createComponent(type, props, maybeSingleChild);
|
|
77
|
-
}
|
package/dist/suspense.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { VNode } from "snabbdom";
|
|
2
|
-
export declare function createSuspense<T extends Record<string, Promise<any>>>(promises: T): {
|
|
3
|
-
[K in keyof T]: Awaited<T[K]>;
|
|
4
|
-
};
|
|
5
|
-
export declare function Suspense(props: {
|
|
6
|
-
fallback: VNode;
|
|
7
|
-
children: VNode | VNode[];
|
|
8
|
-
}): () => VNode | VNode[];
|
|
9
|
-
type SuspensePromiseState<T> = {
|
|
10
|
-
status: "pending";
|
|
11
|
-
value: null;
|
|
12
|
-
error: null;
|
|
13
|
-
} | {
|
|
14
|
-
status: "resolved";
|
|
15
|
-
value: T;
|
|
16
|
-
error: null;
|
|
17
|
-
} | {
|
|
18
|
-
status: "rejected";
|
|
19
|
-
value: null;
|
|
20
|
-
error: string;
|
|
21
|
-
};
|
|
22
|
-
export type SuspensePromise<T> = Promise<T> & SuspensePromiseState<T>;
|
|
23
|
-
export declare function createSuspensePromise<T>(promise: Promise<T>): SuspensePromise<T>;
|
|
24
|
-
export {};
|
|
25
|
-
//# sourceMappingURL=suspense.d.ts.map
|
package/dist/suspense.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"suspense.d.ts","sourceRoot":"","sources":["../src/suspense.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EACnE,QAAQ,EAAE,CAAC,GACV;KACA,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9B,CAuBA;AAQD,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,QAAQ,EAAE,KAAK,CAAC;IAChB,QAAQ,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;CAC3B,yBAmBA;AAED,KAAK,oBAAoB,CAAC,CAAC,IACvB;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAEtE,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,eAAe,CAAC,CAAC,CAAC,CAgEpB"}
|
package/dist/suspense.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { getCurrentComponent } from "./component";
|
|
2
|
-
import { createState } from "./createState";
|
|
3
|
-
import { getCurrentObserver, Signal } from "./observation";
|
|
4
|
-
export function createSuspense(promises) {
|
|
5
|
-
let currentComponent = getCurrentComponent();
|
|
6
|
-
if (!currentComponent) {
|
|
7
|
-
throw new Error("createSuspense must be used in the setup of a component");
|
|
8
|
-
}
|
|
9
|
-
const proxy = {};
|
|
10
|
-
for (const key in promises) {
|
|
11
|
-
const promise = promises[key];
|
|
12
|
-
const suspensePromise = isSuspensePromise(promise)
|
|
13
|
-
? promise
|
|
14
|
-
: createSuspensePromise(promise);
|
|
15
|
-
currentComponent.notifyAsync(suspensePromise);
|
|
16
|
-
Object.defineProperty(proxy, key, {
|
|
17
|
-
get() {
|
|
18
|
-
return suspensePromise.value;
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
return proxy;
|
|
23
|
-
}
|
|
24
|
-
function isSuspensePromise(promise) {
|
|
25
|
-
return "status" in promise;
|
|
26
|
-
}
|
|
27
|
-
export function Suspense(props) {
|
|
28
|
-
const currentComponent = getCurrentComponent();
|
|
29
|
-
const state = createState({
|
|
30
|
-
suspendingPromises: [],
|
|
31
|
-
});
|
|
32
|
-
currentComponent.onAsync((promise) => {
|
|
33
|
-
state.suspendingPromises = state.suspendingPromises.concat(promise);
|
|
34
|
-
});
|
|
35
|
-
return () => {
|
|
36
|
-
const isAllResolved = state.suspendingPromises.every((promise) => promise.status === "resolved");
|
|
37
|
-
console.log(isAllResolved);
|
|
38
|
-
return isAllResolved ? props.children : props.fallback;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
export function createSuspensePromise(promise) {
|
|
42
|
-
const signal = new Signal();
|
|
43
|
-
const state = {
|
|
44
|
-
error: null,
|
|
45
|
-
status: "pending",
|
|
46
|
-
value: null,
|
|
47
|
-
};
|
|
48
|
-
Object.defineProperty(promise, "value", {
|
|
49
|
-
get() {
|
|
50
|
-
const observer = getCurrentObserver();
|
|
51
|
-
if (observer) {
|
|
52
|
-
observer.subscribeSignal(signal);
|
|
53
|
-
}
|
|
54
|
-
return state.value;
|
|
55
|
-
},
|
|
56
|
-
set(newValue) {
|
|
57
|
-
state.value = newValue;
|
|
58
|
-
signal.notify();
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
Object.defineProperty(promise, "error", {
|
|
62
|
-
get() {
|
|
63
|
-
const observer = getCurrentObserver();
|
|
64
|
-
if (observer) {
|
|
65
|
-
observer.subscribeSignal(signal);
|
|
66
|
-
}
|
|
67
|
-
return state.error;
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
Object.defineProperty(promise, "status", {
|
|
71
|
-
get() {
|
|
72
|
-
const observer = getCurrentObserver();
|
|
73
|
-
if (observer) {
|
|
74
|
-
observer.subscribeSignal(signal);
|
|
75
|
-
}
|
|
76
|
-
return state.status;
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
promise
|
|
80
|
-
.then((value) => {
|
|
81
|
-
Object.assign(state, {
|
|
82
|
-
value,
|
|
83
|
-
error: null,
|
|
84
|
-
status: "resolved",
|
|
85
|
-
});
|
|
86
|
-
signal.notify();
|
|
87
|
-
})
|
|
88
|
-
.catch((error) => {
|
|
89
|
-
Object.assign(state, {
|
|
90
|
-
value: null,
|
|
91
|
-
error: String(error),
|
|
92
|
-
status: "rejected",
|
|
93
|
-
});
|
|
94
|
-
signal.notify();
|
|
95
|
-
});
|
|
96
|
-
return promise;
|
|
97
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"class.test.d.ts","sourceRoot":"","sources":["../../src/tests/class.test.ts"],"names":[],"mappings":""}
|
package/dist/tests/class.test.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { jsx, render } from "../vdom";
|
|
3
|
-
import { createState } from "../createState";
|
|
4
|
-
describe("Class Property Support", () => {
|
|
5
|
-
it("should map string class to className", () => {
|
|
6
|
-
const container = document.createElement("div");
|
|
7
|
-
render(jsx("div", { class: "test-class" }), container);
|
|
8
|
-
const div = container.querySelector("div");
|
|
9
|
-
expect(div?.className).toBe("test-class");
|
|
10
|
-
});
|
|
11
|
-
it("should handle multiple classes as string", () => {
|
|
12
|
-
const container = document.createElement("div");
|
|
13
|
-
render(jsx("div", { class: "class-1 class-2 class-3" }), container);
|
|
14
|
-
const div = container.querySelector("div");
|
|
15
|
-
expect(div?.className).toBe("class-1 class-2 class-3");
|
|
16
|
-
});
|
|
17
|
-
it("should handle object notation with true values", () => {
|
|
18
|
-
const container = document.createElement("div");
|
|
19
|
-
render(jsx("div", {
|
|
20
|
-
class: {
|
|
21
|
-
active: true,
|
|
22
|
-
visible: true,
|
|
23
|
-
hidden: false,
|
|
24
|
-
},
|
|
25
|
-
}), container);
|
|
26
|
-
const div = container.querySelector("div");
|
|
27
|
-
expect(div?.classList.contains("active")).toBe(true);
|
|
28
|
-
expect(div?.classList.contains("visible")).toBe(true);
|
|
29
|
-
expect(div?.classList.contains("hidden")).toBe(false);
|
|
30
|
-
});
|
|
31
|
-
it("should handle mixed object notation", () => {
|
|
32
|
-
const container = document.createElement("div");
|
|
33
|
-
render(jsx("div", {
|
|
34
|
-
class: {
|
|
35
|
-
"class-1": true,
|
|
36
|
-
"class-2": false,
|
|
37
|
-
"class-3": true,
|
|
38
|
-
"class-4": false,
|
|
39
|
-
},
|
|
40
|
-
}), container);
|
|
41
|
-
const div = container.querySelector("div");
|
|
42
|
-
expect(div?.className).toBe("class-1 class-3");
|
|
43
|
-
});
|
|
44
|
-
it("should handle empty object notation", () => {
|
|
45
|
-
const container = document.createElement("div");
|
|
46
|
-
render(jsx("div", { class: {} }), container);
|
|
47
|
-
const div = container.querySelector("div");
|
|
48
|
-
expect(div?.className).toBe("");
|
|
49
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
50
|
-
});
|
|
51
|
-
it("should handle all false object notation", () => {
|
|
52
|
-
const container = document.createElement("div");
|
|
53
|
-
render(jsx("div", {
|
|
54
|
-
class: {
|
|
55
|
-
"class-1": false,
|
|
56
|
-
"class-2": false,
|
|
57
|
-
},
|
|
58
|
-
}), container);
|
|
59
|
-
const div = container.querySelector("div");
|
|
60
|
-
expect(div?.className).toBe("");
|
|
61
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
62
|
-
});
|
|
63
|
-
it("should update classes when object notation changes", async () => {
|
|
64
|
-
const container = document.createElement("div");
|
|
65
|
-
let stateFn;
|
|
66
|
-
const App = () => {
|
|
67
|
-
const state = createState({ isActive: true, isVisible: false });
|
|
68
|
-
stateFn = state;
|
|
69
|
-
return () => jsx("div", {
|
|
70
|
-
class: {
|
|
71
|
-
active: state.isActive,
|
|
72
|
-
visible: state.isVisible,
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
};
|
|
76
|
-
render(jsx(App, {}), container);
|
|
77
|
-
const div = container.querySelector("div");
|
|
78
|
-
expect(div?.classList.contains("active")).toBe(true);
|
|
79
|
-
expect(div?.classList.contains("visible")).toBe(false);
|
|
80
|
-
stateFn.isActive = false;
|
|
81
|
-
stateFn.isVisible = true;
|
|
82
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
83
|
-
expect(div?.classList.contains("active")).toBe(false);
|
|
84
|
-
expect(div?.classList.contains("visible")).toBe(true);
|
|
85
|
-
});
|
|
86
|
-
it("should handle hyphenated class names in object notation", () => {
|
|
87
|
-
const container = document.createElement("div");
|
|
88
|
-
render(jsx("div", {
|
|
89
|
-
class: {
|
|
90
|
-
"my-custom-class": true,
|
|
91
|
-
"another-class-name": true,
|
|
92
|
-
"disabled-class": false,
|
|
93
|
-
},
|
|
94
|
-
}), container);
|
|
95
|
-
const div = container.querySelector("div");
|
|
96
|
-
expect(div?.classList.contains("my-custom-class")).toBe(true);
|
|
97
|
-
expect(div?.classList.contains("another-class-name")).toBe(true);
|
|
98
|
-
expect(div?.classList.contains("disabled-class")).toBe(false);
|
|
99
|
-
});
|
|
100
|
-
it("should prefer class over className when both provided", () => {
|
|
101
|
-
const container = document.createElement("div");
|
|
102
|
-
render(jsx("div", { class: "from-class", className: "from-className" }), container);
|
|
103
|
-
const div = container.querySelector("div");
|
|
104
|
-
// class should take precedence
|
|
105
|
-
expect(div?.className).toBe("from-class");
|
|
106
|
-
});
|
|
107
|
-
it("should work with nested components", () => {
|
|
108
|
-
const container = document.createElement("div");
|
|
109
|
-
const Child = () => {
|
|
110
|
-
return () => jsx("span", { class: "child-class" });
|
|
111
|
-
};
|
|
112
|
-
const Parent = () => {
|
|
113
|
-
return () => jsx("div", {
|
|
114
|
-
class: "parent-class",
|
|
115
|
-
children: jsx(Child, {}),
|
|
116
|
-
});
|
|
117
|
-
};
|
|
118
|
-
render(jsx(Parent, {}), container);
|
|
119
|
-
const parentDiv = container.querySelector("div");
|
|
120
|
-
const childSpan = container.querySelector("span");
|
|
121
|
-
expect(parentDiv?.className).toBe("parent-class");
|
|
122
|
-
expect(childSpan?.className).toBe("child-class");
|
|
123
|
-
});
|
|
124
|
-
it("should handle undefined and null class values", () => {
|
|
125
|
-
const container = document.createElement("div");
|
|
126
|
-
render(jsx("div", { class: undefined }), container);
|
|
127
|
-
const div = container.querySelector("div");
|
|
128
|
-
expect(div?.className).toBe("");
|
|
129
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
130
|
-
});
|
|
131
|
-
it("should remove class attribute when empty string is provided", () => {
|
|
132
|
-
const container = document.createElement("div");
|
|
133
|
-
render(jsx("div", { class: "" }), container);
|
|
134
|
-
const div = container.querySelector("div");
|
|
135
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
136
|
-
});
|
|
137
|
-
it("should remove class attribute when null is provided", () => {
|
|
138
|
-
const container = document.createElement("div");
|
|
139
|
-
render(jsx("div", { class: null }), container);
|
|
140
|
-
const div = container.querySelector("div");
|
|
141
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
142
|
-
});
|
|
143
|
-
it("should remove class attribute when object notation results in empty string", () => {
|
|
144
|
-
const container = document.createElement("div");
|
|
145
|
-
render(jsx("div", {
|
|
146
|
-
class: {
|
|
147
|
-
active: false,
|
|
148
|
-
visible: false,
|
|
149
|
-
},
|
|
150
|
-
}), container);
|
|
151
|
-
const div = container.querySelector("div");
|
|
152
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
153
|
-
});
|
|
154
|
-
it("should remove class attribute when updating from non-empty to empty string", async () => {
|
|
155
|
-
const container = document.createElement("div");
|
|
156
|
-
let stateFn;
|
|
157
|
-
const App = () => {
|
|
158
|
-
const state = createState({ className: "initial" });
|
|
159
|
-
stateFn = state;
|
|
160
|
-
return () => jsx("div", { class: state.className });
|
|
161
|
-
};
|
|
162
|
-
render(jsx(App, {}), container);
|
|
163
|
-
const div = container.querySelector("div");
|
|
164
|
-
expect(div?.className).toBe("initial");
|
|
165
|
-
expect(div?.hasAttribute("class")).toBe(true);
|
|
166
|
-
stateFn.className = "";
|
|
167
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
168
|
-
expect(div?.hasAttribute("class")).toBe(false);
|
|
169
|
-
});
|
|
170
|
-
it("should handle dynamic string class updates", async () => {
|
|
171
|
-
const container = document.createElement("div");
|
|
172
|
-
let stateFn;
|
|
173
|
-
const App = () => {
|
|
174
|
-
const state = createState({ className: "initial" });
|
|
175
|
-
stateFn = state;
|
|
176
|
-
return () => jsx("div", { class: state.className });
|
|
177
|
-
};
|
|
178
|
-
render(jsx(App, {}), container);
|
|
179
|
-
const div = container.querySelector("div");
|
|
180
|
-
expect(div?.className).toBe("initial");
|
|
181
|
-
stateFn.className = "updated";
|
|
182
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
183
|
-
expect(div?.className).toBe("updated");
|
|
184
|
-
});
|
|
185
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"complex-rendering.test.d.ts","sourceRoot":"","sources":["../../src/tests/complex-rendering.test.ts"],"names":[],"mappings":""}
|