what-core 0.6.2 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/compiler.d.ts +30 -0
- package/devtools.d.ts +2 -0
- package/dist/compiler.js +1787 -0
- package/dist/compiler.js.map +7 -0
- package/dist/compiler.min.js +2 -0
- package/dist/compiler.min.js.map +7 -0
- package/dist/devtools.js +10 -0
- package/dist/devtools.js.map +7 -0
- package/dist/devtools.min.js +2 -0
- package/dist/devtools.min.js.map +7 -0
- package/dist/index.js +330 -382
- package/dist/index.js.map +4 -4
- package/dist/index.min.js +62 -62
- package/dist/index.min.js.map +4 -4
- package/dist/render.js +262 -21
- package/dist/render.js.map +4 -4
- package/dist/render.min.js +58 -1
- package/dist/render.min.js.map +4 -4
- package/dist/testing.js +3 -0
- package/dist/testing.js.map +2 -2
- package/dist/testing.min.js +1 -1
- package/dist/testing.min.js.map +2 -2
- package/index.d.ts +176 -1
- package/jsx-runtime.d.ts +622 -0
- package/package.json +20 -2
- package/render.d.ts +1 -1
- package/src/agent-context.js +1 -1
- package/src/compiler.js +18 -0
- package/src/components.js +73 -27
- package/src/devtools.js +4 -0
- package/src/dom.js +7 -0
- package/src/guardrails.js +3 -4
- package/src/hooks.js +0 -11
- package/src/index.js +5 -9
- package/src/render.js +91 -24
- package/testing.d.ts +1 -1
- package/dist/a11y.js +0 -440
- package/dist/animation.js +0 -548
- package/dist/components.js +0 -229
- package/dist/data.js +0 -638
- package/dist/dom.js +0 -439
- package/dist/form.js +0 -509
- package/dist/h.js +0 -152
- package/dist/head.js +0 -51
- package/dist/helpers.js +0 -140
- package/dist/hooks.js +0 -210
- package/dist/reactive.js +0 -432
- package/dist/scheduler.js +0 -246
- package/dist/skeleton.js +0 -363
- package/dist/store.js +0 -83
- package/dist/what.js +0 -117
package/dist/helpers.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { signal, effect, __DEV__ } from './reactive.js';
|
|
2
|
-
let _eachWarned = false;
|
|
3
|
-
export function each(list, fn, keyFn) {
|
|
4
|
-
if (!_eachWarned) {
|
|
5
|
-
_eachWarned = true;
|
|
6
|
-
console.warn('[what] each() is deprecated. Use the <For> component or Array.map() instead.');
|
|
7
|
-
}
|
|
8
|
-
if (!list || list.length === 0) return [];
|
|
9
|
-
return list.map((item, index) => {
|
|
10
|
-
const vnode = fn(item, index);
|
|
11
|
-
if (keyFn && vnode && typeof vnode === 'object') {
|
|
12
|
-
vnode.key = keyFn(item, index);
|
|
13
|
-
}
|
|
14
|
-
return vnode;
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
export function cls(...args) {
|
|
18
|
-
const classes = [];
|
|
19
|
-
for (const arg of args) {
|
|
20
|
-
if (!arg) continue;
|
|
21
|
-
if (typeof arg === 'string') {
|
|
22
|
-
classes.push(arg);
|
|
23
|
-
} else if (typeof arg === 'object') {
|
|
24
|
-
for (const [key, val] of Object.entries(arg)) {
|
|
25
|
-
if (val) classes.push(key);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return classes.join(' ');
|
|
30
|
-
}
|
|
31
|
-
export function style(obj) {
|
|
32
|
-
if (typeof obj === 'string') return obj;
|
|
33
|
-
return Object.entries(obj)
|
|
34
|
-
.filter(([, v]) => v != null && v !== '')
|
|
35
|
-
.map(([k, v]) => `${camelToKebab(k)}:${v}`)
|
|
36
|
-
.join(';');
|
|
37
|
-
}
|
|
38
|
-
function camelToKebab(str) {
|
|
39
|
-
return str.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
40
|
-
}
|
|
41
|
-
export function debounce(fn, ms) {
|
|
42
|
-
let timer;
|
|
43
|
-
return (...args) => {
|
|
44
|
-
clearTimeout(timer);
|
|
45
|
-
timer = setTimeout(() => fn(...args), ms);
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
export function throttle(fn, ms) {
|
|
49
|
-
let last = 0;
|
|
50
|
-
return (...args) => {
|
|
51
|
-
const now = Date.now();
|
|
52
|
-
if (now - last >= ms) {
|
|
53
|
-
last = now;
|
|
54
|
-
fn(...args);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
let _getCurrentComponentRef = null;
|
|
59
|
-
export function _setComponentRef(fn) { _getCurrentComponentRef = fn; }
|
|
60
|
-
export function useMediaQuery(query) {
|
|
61
|
-
if (typeof window === 'undefined') return signal(false);
|
|
62
|
-
const mq = window.matchMedia(query);
|
|
63
|
-
const s = signal(mq.matches);
|
|
64
|
-
const handler = (e) => s.set(e.matches);
|
|
65
|
-
mq.addEventListener('change', handler);
|
|
66
|
-
const ctx = _getCurrentComponentRef?.();
|
|
67
|
-
if (ctx) {
|
|
68
|
-
ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
|
|
69
|
-
ctx._cleanupCallbacks.push(() => mq.removeEventListener('change', handler));
|
|
70
|
-
}
|
|
71
|
-
return s;
|
|
72
|
-
}
|
|
73
|
-
export function useLocalStorage(key, initial) {
|
|
74
|
-
let stored;
|
|
75
|
-
try {
|
|
76
|
-
const raw = localStorage.getItem(key);
|
|
77
|
-
stored = raw !== null ? JSON.parse(raw) : initial;
|
|
78
|
-
} catch {
|
|
79
|
-
stored = initial;
|
|
80
|
-
}
|
|
81
|
-
const s = signal(stored);
|
|
82
|
-
const dispose = effect(() => {
|
|
83
|
-
try {
|
|
84
|
-
localStorage.setItem(key, JSON.stringify(s()));
|
|
85
|
-
} catch (e) {
|
|
86
|
-
if (__DEV__) console.warn('[what] localStorage write failed (quota exceeded?):', e);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
let storageHandler = null;
|
|
90
|
-
if (typeof window !== 'undefined') {
|
|
91
|
-
storageHandler = (e) => {
|
|
92
|
-
if (e.key === key && e.newValue !== null) {
|
|
93
|
-
try { s.set(JSON.parse(e.newValue)); } catch (err) {
|
|
94
|
-
if (__DEV__) console.warn('[what] localStorage parse failed:', err);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
window.addEventListener('storage', storageHandler);
|
|
99
|
-
}
|
|
100
|
-
const ctx = _getCurrentComponentRef?.();
|
|
101
|
-
if (ctx) {
|
|
102
|
-
ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
|
|
103
|
-
ctx._cleanupCallbacks.push(() => {
|
|
104
|
-
dispose();
|
|
105
|
-
if (storageHandler) window.removeEventListener('storage', storageHandler);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
return s;
|
|
109
|
-
}
|
|
110
|
-
export function Portal({ target, children }) {
|
|
111
|
-
if (typeof document === 'undefined') return null;
|
|
112
|
-
const container = typeof target === 'string'
|
|
113
|
-
? document.querySelector(target)
|
|
114
|
-
: target;
|
|
115
|
-
if (!container) return null;
|
|
116
|
-
return { tag: '__portal', props: { container }, children: Array.isArray(children) ? children : [children], _vnode: true };
|
|
117
|
-
}
|
|
118
|
-
export function useClickOutside(ref, handler) {
|
|
119
|
-
if (typeof document === 'undefined') return;
|
|
120
|
-
const listener = (e) => {
|
|
121
|
-
const el = ref.current || ref;
|
|
122
|
-
if (!el || el.contains(e.target)) return;
|
|
123
|
-
handler(e);
|
|
124
|
-
};
|
|
125
|
-
document.addEventListener('mousedown', listener);
|
|
126
|
-
document.addEventListener('touchstart', listener);
|
|
127
|
-
const ctx = _getCurrentComponentRef?.();
|
|
128
|
-
if (ctx) {
|
|
129
|
-
ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
|
|
130
|
-
ctx._cleanupCallbacks.push(() => {
|
|
131
|
-
document.removeEventListener('mousedown', listener);
|
|
132
|
-
document.removeEventListener('touchstart', listener);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
export function transition(name, active) {
|
|
137
|
-
return {
|
|
138
|
-
class: active ? `${name}-enter ${name}-enter-active` : `${name}-leave ${name}-leave-active`,
|
|
139
|
-
};
|
|
140
|
-
}
|
package/dist/hooks.js
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import { signal, computed, effect, batch, untrack, __DEV__ } from './reactive.js';
|
|
2
|
-
import { getCurrentComponent } from './dom.js';
|
|
3
|
-
function getCtx() {
|
|
4
|
-
const ctx = getCurrentComponent();
|
|
5
|
-
if (!ctx) {
|
|
6
|
-
throw new Error(
|
|
7
|
-
'[what] Hooks must be called inside a component function. ' +
|
|
8
|
-
'If you need reactive state outside a component, use signal() directly.'
|
|
9
|
-
);
|
|
10
|
-
}
|
|
11
|
-
return ctx;
|
|
12
|
-
}
|
|
13
|
-
function getHook(ctx) {
|
|
14
|
-
const index = ctx.hookIndex++;
|
|
15
|
-
return { index, exists: index < ctx.hooks.length };
|
|
16
|
-
}
|
|
17
|
-
let _useMemoNoDepsWarned = false;
|
|
18
|
-
export function useState(initial) {
|
|
19
|
-
const ctx = getCtx();
|
|
20
|
-
const { index, exists } = getHook(ctx);
|
|
21
|
-
if (!exists) {
|
|
22
|
-
const s = signal(typeof initial === 'function' ? initial() : initial);
|
|
23
|
-
ctx.hooks[index] = s;
|
|
24
|
-
}
|
|
25
|
-
const s = ctx.hooks[index];
|
|
26
|
-
return [s(), s.set];
|
|
27
|
-
}
|
|
28
|
-
export function useSignal(initial) {
|
|
29
|
-
const ctx = getCtx();
|
|
30
|
-
const { index, exists } = getHook(ctx);
|
|
31
|
-
if (!exists) {
|
|
32
|
-
ctx.hooks[index] = signal(typeof initial === 'function' ? initial() : initial);
|
|
33
|
-
}
|
|
34
|
-
return ctx.hooks[index];
|
|
35
|
-
}
|
|
36
|
-
export function useComputed(fn) {
|
|
37
|
-
const ctx = getCtx();
|
|
38
|
-
const { index, exists } = getHook(ctx);
|
|
39
|
-
if (!exists) {
|
|
40
|
-
ctx.hooks[index] = computed(fn);
|
|
41
|
-
}
|
|
42
|
-
return ctx.hooks[index];
|
|
43
|
-
}
|
|
44
|
-
export function useEffect(fn, deps) {
|
|
45
|
-
const ctx = getCtx();
|
|
46
|
-
const { index, exists } = getHook(ctx);
|
|
47
|
-
if (!exists) {
|
|
48
|
-
ctx.hooks[index] = { deps: undefined, cleanup: null };
|
|
49
|
-
}
|
|
50
|
-
const hook = ctx.hooks[index];
|
|
51
|
-
if (depsChanged(hook.deps, deps)) {
|
|
52
|
-
queueMicrotask(() => {
|
|
53
|
-
if (ctx.disposed) return;
|
|
54
|
-
if (hook.cleanup) hook.cleanup();
|
|
55
|
-
hook.cleanup = fn() || null;
|
|
56
|
-
});
|
|
57
|
-
hook.deps = deps;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
export function useMemo(fn, deps) {
|
|
61
|
-
const ctx = getCtx();
|
|
62
|
-
const { index, exists } = getHook(ctx);
|
|
63
|
-
if (__DEV__ && deps === undefined && !_useMemoNoDepsWarned) {
|
|
64
|
-
_useMemoNoDepsWarned = true;
|
|
65
|
-
console.warn(
|
|
66
|
-
'[what] useMemo() called without a deps array. ' +
|
|
67
|
-
'This recomputes every render. Use useComputed() for signal-derived values, ' +
|
|
68
|
-
'or pass deps to useMemo().'
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
if (!exists) {
|
|
72
|
-
ctx.hooks[index] = { value: undefined, deps: undefined };
|
|
73
|
-
}
|
|
74
|
-
const hook = ctx.hooks[index];
|
|
75
|
-
if (depsChanged(hook.deps, deps)) {
|
|
76
|
-
hook.value = fn();
|
|
77
|
-
hook.deps = deps;
|
|
78
|
-
}
|
|
79
|
-
return hook.value;
|
|
80
|
-
}
|
|
81
|
-
export function useCallback(fn, deps) {
|
|
82
|
-
return useMemo(() => fn, deps);
|
|
83
|
-
}
|
|
84
|
-
export function useRef(initial) {
|
|
85
|
-
const ctx = getCtx();
|
|
86
|
-
const { index, exists } = getHook(ctx);
|
|
87
|
-
if (!exists) {
|
|
88
|
-
ctx.hooks[index] = { current: initial };
|
|
89
|
-
}
|
|
90
|
-
return ctx.hooks[index];
|
|
91
|
-
}
|
|
92
|
-
export function useContext(context) {
|
|
93
|
-
let ctx = getCurrentComponent();
|
|
94
|
-
if (__DEV__ && !ctx) {
|
|
95
|
-
console.warn(
|
|
96
|
-
`[what] useContext(${context?.displayName || 'Context'}) called outside of component render. ` +
|
|
97
|
-
'useContext must be called during component rendering, not inside effects or event handlers. ' +
|
|
98
|
-
'Store the context value in a variable during render and use that variable in your callback.'
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
while (ctx) {
|
|
102
|
-
if (ctx._contextValues && ctx._contextValues.has(context)) {
|
|
103
|
-
const val = ctx._contextValues.get(context);
|
|
104
|
-
return (val && val._signal) ? val() : val;
|
|
105
|
-
}
|
|
106
|
-
ctx = ctx._parentCtx;
|
|
107
|
-
}
|
|
108
|
-
return context._defaultValue;
|
|
109
|
-
}
|
|
110
|
-
export function createContext(defaultValue) {
|
|
111
|
-
const context = {
|
|
112
|
-
_defaultValue: defaultValue,
|
|
113
|
-
Provider: ({ value, children }) => {
|
|
114
|
-
const ctx = getCtx();
|
|
115
|
-
if (!ctx._contextValues) ctx._contextValues = new Map();
|
|
116
|
-
if (!ctx._contextSignals) ctx._contextSignals = new Map();
|
|
117
|
-
if (!ctx._contextSignals.has(context)) {
|
|
118
|
-
const s = signal(value);
|
|
119
|
-
ctx._contextSignals.set(context, s);
|
|
120
|
-
ctx._contextValues.set(context, s);
|
|
121
|
-
} else {
|
|
122
|
-
ctx._contextSignals.get(context).set(value);
|
|
123
|
-
}
|
|
124
|
-
return children;
|
|
125
|
-
},
|
|
126
|
-
Consumer: ({ children }) => {
|
|
127
|
-
const value = useContext(context);
|
|
128
|
-
return typeof children === 'function' ? children(value) : children;
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
return context;
|
|
132
|
-
}
|
|
133
|
-
export function useReducer(reducer, initialState, init) {
|
|
134
|
-
const ctx = getCtx();
|
|
135
|
-
const { index, exists } = getHook(ctx);
|
|
136
|
-
if (!exists) {
|
|
137
|
-
const initial = init ? init(initialState) : initialState;
|
|
138
|
-
const s = signal(initial);
|
|
139
|
-
const dispatch = (action) => {
|
|
140
|
-
s.set(prev => reducer(prev, action));
|
|
141
|
-
};
|
|
142
|
-
ctx.hooks[index] = { signal: s, dispatch };
|
|
143
|
-
}
|
|
144
|
-
const hook = ctx.hooks[index];
|
|
145
|
-
return [hook.signal(), hook.dispatch];
|
|
146
|
-
}
|
|
147
|
-
export function onMount(fn) {
|
|
148
|
-
const ctx = getCtx();
|
|
149
|
-
if (!ctx.mounted) {
|
|
150
|
-
ctx._mountCallbacks = ctx._mountCallbacks || [];
|
|
151
|
-
ctx._mountCallbacks.push(fn);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
export function onCleanup(fn) {
|
|
155
|
-
const ctx = getCtx();
|
|
156
|
-
ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
|
|
157
|
-
ctx._cleanupCallbacks.push(fn);
|
|
158
|
-
}
|
|
159
|
-
export function createResource(fetcher, options = {}) {
|
|
160
|
-
const data = signal(options.initialValue ?? null);
|
|
161
|
-
const loading = signal(!options.initialValue);
|
|
162
|
-
const error = signal(null);
|
|
163
|
-
let controller = null;
|
|
164
|
-
const refetch = async (source) => {
|
|
165
|
-
if (controller) controller.abort();
|
|
166
|
-
controller = new AbortController();
|
|
167
|
-
const { signal: abortSignal } = controller;
|
|
168
|
-
loading.set(true);
|
|
169
|
-
error.set(null);
|
|
170
|
-
try {
|
|
171
|
-
const result = await fetcher(source, { signal: abortSignal });
|
|
172
|
-
if (!abortSignal.aborted) {
|
|
173
|
-
batch(() => {
|
|
174
|
-
data.set(result);
|
|
175
|
-
loading.set(false);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
} catch (e) {
|
|
179
|
-
if (!abortSignal.aborted) {
|
|
180
|
-
batch(() => {
|
|
181
|
-
error.set(e);
|
|
182
|
-
loading.set(false);
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
const mutate = (value) => {
|
|
188
|
-
data.set(typeof value === 'function' ? value(data()) : value);
|
|
189
|
-
};
|
|
190
|
-
const ctx = getCurrentComponent?.();
|
|
191
|
-
if (ctx) {
|
|
192
|
-
ctx._cleanupCallbacks = ctx._cleanupCallbacks || [];
|
|
193
|
-
ctx._cleanupCallbacks.push(() => {
|
|
194
|
-
if (controller) controller.abort();
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
if (!options.initialValue) {
|
|
198
|
-
refetch(options.source);
|
|
199
|
-
}
|
|
200
|
-
return [data, { loading, error, refetch, mutate }];
|
|
201
|
-
}
|
|
202
|
-
function depsChanged(oldDeps, newDeps) {
|
|
203
|
-
if (oldDeps === undefined) return true;
|
|
204
|
-
if (!oldDeps || !newDeps) return true;
|
|
205
|
-
if (oldDeps.length !== newDeps.length) return true;
|
|
206
|
-
for (let i = 0; i < oldDeps.length; i++) {
|
|
207
|
-
if (!Object.is(oldDeps[i], newDeps[i])) return true;
|
|
208
|
-
}
|
|
209
|
-
return false;
|
|
210
|
-
}
|