rask-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +263 -0
- package/dist/component.d.ts +21 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +128 -0
- package/dist/context.d.ts +5 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +29 -0
- package/dist/createAsync.d.ts +16 -0
- package/dist/createAsync.d.ts.map +1 -0
- package/dist/createAsync.js +24 -0
- package/dist/createAsyncState.d.ts +16 -0
- package/dist/createAsyncState.d.ts.map +1 -0
- package/dist/createAsyncState.js +24 -0
- package/dist/createContext.d.ts +5 -0
- package/dist/createContext.d.ts.map +1 -0
- package/dist/createContext.js +29 -0
- package/dist/createMutation.d.ts +20 -0
- package/dist/createMutation.d.ts.map +1 -0
- package/dist/createMutation.js +53 -0
- package/dist/createQuery.d.ts +19 -0
- package/dist/createQuery.d.ts.map +1 -0
- package/dist/createQuery.js +57 -0
- package/dist/createRef.d.ts +5 -0
- package/dist/createRef.d.ts.map +1 -0
- package/dist/createRef.js +7 -0
- package/dist/createState.d.ts +2 -0
- package/dist/createState.d.ts.map +1 -0
- package/dist/createState.js +52 -0
- package/dist/error.d.ts +5 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/jsx-dev-runtime.d.ts +4 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +5 -0
- package/dist/jsx-runtime.d.ts +15 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +19 -0
- package/dist/jsx.d.ts +257 -0
- package/dist/jsx.d.ts.map +1 -0
- package/dist/jsx.js +42 -0
- package/dist/observation.d.ts +17 -0
- package/dist/observation.d.ts.map +1 -0
- package/dist/observation.js +50 -0
- package/dist/render.d.ts +7 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +65 -0
- package/dist/suspense.d.ts +25 -0
- package/dist/suspense.d.ts.map +1 -0
- package/dist/suspense.js +97 -0
- package/package.json +41 -0
package/dist/render.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
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 === "ref") {
|
|
35
|
+
data.hook = data.hook || {};
|
|
36
|
+
const existingInsertHook = data.hook?.insert;
|
|
37
|
+
data.hook.insert = (vnode) => {
|
|
38
|
+
existingInsertHook?.(vnode);
|
|
39
|
+
props.ref(vnode.elm || null);
|
|
40
|
+
};
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (key.startsWith("on")) {
|
|
44
|
+
data.on = data.on || {};
|
|
45
|
+
data.on[key.substring(2).toLocaleLowerCase()] = props[key];
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
49
|
+
data.attrs = data.attrs || {};
|
|
50
|
+
data.attrs[key] = props[key];
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (type === "svg") {
|
|
54
|
+
data.attrs = data.attrs || {};
|
|
55
|
+
data.attrs[key] = props[key];
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
data.props = data.props || {};
|
|
59
|
+
data.props[key] = props[key];
|
|
60
|
+
}
|
|
61
|
+
return h(type, data, flatChildren);
|
|
62
|
+
}
|
|
63
|
+
const maybeSingleChild = flatChildren.length === 1 ? flatChildren[0] : flatChildren;
|
|
64
|
+
return createComponent(type, props, maybeSingleChild);
|
|
65
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rask-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./jsx-runtime": {
|
|
13
|
+
"types": "./dist/jsx-runtime.d.ts",
|
|
14
|
+
"import": "./dist/jsx-runtime.js"
|
|
15
|
+
},
|
|
16
|
+
"./jsx-dev-runtime": {
|
|
17
|
+
"types": "./dist/jsx-dev-runtime.d.ts",
|
|
18
|
+
"import": "./dist/jsx-dev-runtime.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc && cp src/jsx.d.ts dist/",
|
|
26
|
+
"dev": "tsc --watch",
|
|
27
|
+
"test": "vitest",
|
|
28
|
+
"test:ui": "vitest --ui",
|
|
29
|
+
"test:run": "vitest run"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@vitest/ui": "^4.0.7",
|
|
33
|
+
"happy-dom": "^20.0.10",
|
|
34
|
+
"jsdom": "^27.1.0",
|
|
35
|
+
"typescript": "^5.7.3",
|
|
36
|
+
"vitest": "^4.0.7"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"snabbdom": "^3.6.3"
|
|
40
|
+
}
|
|
41
|
+
}
|