@mizchi/luna 0.1.4 → 0.1.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/index.d.ts DELETED
@@ -1,564 +0,0 @@
1
- /**
2
- * SolidJS-compatible TypeScript definitions for Luna
3
- */
4
-
5
- // MoonBit tuple type - exported as object with _0 and _1 properties
6
- export type MoonBitTuple<A, B> = { _0: A; _1: B };
7
-
8
- // ============================================================================
9
- // Signal API (SolidJS-style)
10
- // ============================================================================
11
-
12
- /** Signal getter function */
13
- export type Accessor<T> = () => T;
14
-
15
- /** Signal setter function - accepts value or updater function */
16
- export type Setter<T> = (value: T | ((prev: T) => T)) => void;
17
-
18
- /** Signal tuple [getter, setter] */
19
- export type Signal<T> = [Accessor<T>, Setter<T>];
20
-
21
- /**
22
- * Creates a reactive signal (SolidJS-style)
23
- * @example
24
- * const [count, setCount] = createSignal(0);
25
- * count(); // 0
26
- * setCount(1);
27
- * setCount(c => c + 1);
28
- */
29
- export function createSignal<T>(initialValue: T): Signal<T>;
30
-
31
- /**
32
- * Creates a reactive effect (SolidJS-style)
33
- * @example
34
- * createEffect(() => console.log(count()));
35
- */
36
- export function createEffect(fn: () => void): () => void;
37
-
38
- /**
39
- * Creates a memoized computed value (SolidJS-style)
40
- * @example
41
- * const doubled = createMemo(() => count() * 2);
42
- */
43
- export function createMemo<T>(compute: () => T): Accessor<T>;
44
-
45
- /** Start a batch update */
46
- export function batchStart(): void;
47
-
48
- /** End a batch update and run pending effects */
49
- export function batchEnd(): void;
50
-
51
- /** Run a function in a batch - all signal updates are batched */
52
- export function batch<T>(fn: () => T): T;
53
-
54
- /** Run a function without tracking dependencies (SolidJS: untrack) */
55
- export function untrack<T>(fn: () => T): T;
56
-
57
- /** Register a cleanup function inside an effect */
58
- export function onCleanup(cleanup: () => void): void;
59
-
60
- // ============================================================================
61
- // Utility functions (SolidJS-style)
62
- // ============================================================================
63
-
64
- /**
65
- * Explicit dependency tracking helper (SolidJS-style)
66
- * Wraps a function to explicitly specify which signals to track
67
- * @example
68
- * createEffect(on(count, (value, prev) => console.log(value, prev)));
69
- * createEffect(on([a, b], ([a, b]) => console.log(a, b)));
70
- */
71
- export function on<T, U>(
72
- deps: Accessor<T>,
73
- fn: (input: T, prevInput: T | undefined, prevValue: U | undefined) => U,
74
- options?: { defer?: boolean }
75
- ): () => U | undefined;
76
- export function on<T extends readonly Accessor<any>[], U>(
77
- deps: T,
78
- fn: (
79
- input: { [K in keyof T]: T[K] extends Accessor<infer V> ? V : never },
80
- prevInput: { [K in keyof T]: T[K] extends Accessor<infer V> ? V : never } | undefined,
81
- prevValue: U | undefined
82
- ) => U,
83
- options?: { defer?: boolean }
84
- ): () => U | undefined;
85
-
86
- /**
87
- * Merge multiple props objects (SolidJS-style)
88
- * Event handlers and refs are merged, other props are overwritten
89
- * @example
90
- * const merged = mergeProps(defaultProps, props);
91
- */
92
- export function mergeProps<T extends object>(...sources: (Partial<T> | undefined)[]): T;
93
-
94
- /**
95
- * Split props into multiple objects based on key lists (SolidJS-style)
96
- * @example
97
- * const [local, others] = splitProps(props, ["class", "style"]);
98
- */
99
- export function splitProps<T extends object, K extends (keyof T)[]>(
100
- props: T,
101
- ...keys: K[]
102
- ): [...{ [I in keyof K]: Pick<T, K[I] extends (keyof T)[] ? K[I][number] : never> }, Omit<T, K[number][number]>];
103
-
104
- // ============================================================================
105
- // Owner-based scope management
106
- // ============================================================================
107
-
108
- /** Opaque Owner type */
109
- export interface Owner {
110
- readonly __brand: unique symbol;
111
- }
112
-
113
- /** Create a new reactive root scope */
114
- export function createRoot<T>(fn: (dispose: () => void) => T): T;
115
-
116
- /** Get the current owner (if any) */
117
- export function getOwner(): Owner | undefined;
118
-
119
- /** Run a function with a specific owner as current */
120
- export function runWithOwner<T>(owner: Owner, fn: () => T): T;
121
-
122
- /** Check if currently inside an owner scope */
123
- export function hasOwner(): boolean;
124
-
125
- /** Run a function once (SolidJS-style onMount) */
126
- export function onMount(fn: () => void): void;
127
-
128
- // ============================================================================
129
- // DOM API
130
- // ============================================================================
131
-
132
- /** Opaque DOM Node type */
133
- export interface Node {
134
- readonly __brand: unique symbol;
135
- }
136
-
137
- /** Event handler types */
138
- export type MouseEventHandler = (event: MouseEvent) => void;
139
- export type InputEventHandler = (event: InputEvent) => void;
140
- export type KeyboardEventHandler = (event: KeyboardEvent) => void;
141
- export type FocusEventHandler = (event: FocusEvent) => void;
142
- export type FormEventHandler = (event: Event) => void;
143
- export type ChangeEventHandler = (event: Event) => void;
144
-
145
- /** HandlerMap builder for event handlers (method chaining) */
146
- export interface HandlerMap {
147
- click(handler: MouseEventHandler): HandlerMap;
148
- dblclick(handler: MouseEventHandler): HandlerMap;
149
- input(handler: InputEventHandler): HandlerMap;
150
- change(handler: ChangeEventHandler): HandlerMap;
151
- submit(handler: FormEventHandler): HandlerMap;
152
- keydown(handler: KeyboardEventHandler): HandlerMap;
153
- keyup(handler: KeyboardEventHandler): HandlerMap;
154
- keypress(handler: KeyboardEventHandler): HandlerMap;
155
- focus(handler: FocusEventHandler): HandlerMap;
156
- blur(handler: FocusEventHandler): HandlerMap;
157
- mouseenter(handler: MouseEventHandler): HandlerMap;
158
- mouseleave(handler: MouseEventHandler): HandlerMap;
159
- mouseover(handler: MouseEventHandler): HandlerMap;
160
- mouseout(handler: MouseEventHandler): HandlerMap;
161
- mousedown(handler: MouseEventHandler): HandlerMap;
162
- mouseup(handler: MouseEventHandler): HandlerMap;
163
- }
164
-
165
- /** Create event handler map builder */
166
- export function events(): HandlerMap;
167
-
168
- // Text
169
- export function text(content: string): Node;
170
- export function textDyn(getter: () => string): Node;
171
-
172
- // Rendering
173
- export function render(container: Element, node: Node): void;
174
- export function mount(container: Element, node: Node): void;
175
- export function show(condition: () => boolean, render: () => Node): Node;
176
-
177
- // List rendering (low-level)
178
- export function forEach<T>(
179
- items: () => T[],
180
- renderItem: (item: T, index: number) => Node
181
- ): Node;
182
-
183
- // ============================================================================
184
- // SolidJS-compatible Components
185
- // ============================================================================
186
-
187
- /** For component props */
188
- export interface ForProps<T, U extends Node> {
189
- each: Accessor<T[]> | T[];
190
- fallback?: Node;
191
- children: (item: T, index: Accessor<number>) => U;
192
- }
193
-
194
- /**
195
- * For component for list rendering (SolidJS-style)
196
- * @example
197
- * <For each={items}>{(item, index) => <div>{item}</div>}</For>
198
- */
199
- export function For<T, U extends Node>(props: ForProps<T, U>): Node;
200
-
201
- /** Show component props */
202
- export interface ShowProps<T> {
203
- when: T | Accessor<T>;
204
- fallback?: Node;
205
- children: Node | ((item: NonNullable<T>) => Node);
206
- }
207
-
208
- /**
209
- * Show component for conditional rendering (SolidJS-style)
210
- * Note: fallback prop is not yet supported (Luna limitation)
211
- * @example
212
- * <Show when={isVisible}><div>Visible!</div></Show>
213
- */
214
- export function Show<T>(props: ShowProps<T>): Node;
215
-
216
- /** Index component props */
217
- export interface IndexProps<T, U extends Node> {
218
- each: Accessor<T[]> | T[];
219
- fallback?: Node;
220
- children: (item: Accessor<T>, index: number) => U;
221
- }
222
-
223
- /**
224
- * Index component for index-based list rendering (SolidJS-style)
225
- * Unlike For which tracks items by reference, Index tracks by index position
226
- * @example
227
- * <Index each={items}>{(item, index) => <div>{item()}</div>}</Index>
228
- */
229
- export function Index<T, U extends Node>(props: IndexProps<T, U>): Node;
230
-
231
- /** Provider component props */
232
- export interface ProviderProps<T> {
233
- context: Context<T>;
234
- value: T;
235
- children: Node | (() => Node);
236
- }
237
-
238
- /**
239
- * Provider component for Context (SolidJS-style)
240
- * @example
241
- * <Provider context={ThemeContext} value="dark"><App /></Provider>
242
- */
243
- export function Provider<T>(props: ProviderProps<T>): Node;
244
-
245
- /** Match component result (internal) */
246
- export interface MatchResult<T> {
247
- readonly __isMatch: true;
248
- when: () => boolean;
249
- children: T | (() => T);
250
- }
251
-
252
- /** Switch component props */
253
- export interface SwitchProps {
254
- fallback?: Node;
255
- children: MatchResult<Node>[];
256
- }
257
-
258
- /**
259
- * Switch component for conditional rendering with multiple branches (SolidJS-style)
260
- * @example
261
- * <Switch fallback={<div>Not found</div>}>
262
- * <Match when={isA}><A /></Match>
263
- * <Match when={isB}><B /></Match>
264
- * </Switch>
265
- */
266
- export function Switch(props: SwitchProps): Node;
267
-
268
- /** Match component props */
269
- export interface MatchProps<T> {
270
- when: T | Accessor<T>;
271
- children: Node | ((item: NonNullable<T>) => Node);
272
- }
273
-
274
- /**
275
- * Match component for use inside Switch (SolidJS-style)
276
- */
277
- export function Match<T>(props: MatchProps<T>): MatchResult<Node>;
278
-
279
- // ============================================================================
280
- // Portal API (SolidJS-style)
281
- // ============================================================================
282
-
283
- /** Portal component props */
284
- export interface PortalProps {
285
- /** Target element or CSS selector to mount to (defaults to document.body) */
286
- mount?: Element | string;
287
- /** Whether to use Shadow DOM for encapsulation */
288
- useShadow?: boolean;
289
- /** Children to render in the portal */
290
- children: Node | Node[] | (() => Node);
291
- }
292
-
293
- /**
294
- * Portal component for rendering outside the component tree (SolidJS-style)
295
- * Teleports children to a different DOM location
296
- * @example
297
- * Portal({ children: modal() }) // renders to body
298
- * Portal({ mount: "#modal-root", children: modal() }) // renders to #modal-root
299
- * Portal({ useShadow: true, children: modal() }) // renders with Shadow DOM
300
- */
301
- export function Portal(props: PortalProps): Node;
302
-
303
- /** Low-level portal to body */
304
- export function portalToBody(children: Node[]): Node;
305
-
306
- /** Low-level portal to CSS selector */
307
- export function portalToSelector(selector: string, children: Node[]): Node;
308
-
309
- /** Low-level portal with Shadow DOM */
310
- export function portalWithShadow(children: Node[]): Node;
311
-
312
- /** Low-level portal to element with Shadow DOM */
313
- export function portalToElementWithShadow(mount: Element, children: Node[]): Node;
314
-
315
- // Low-level element creation (MoonBit API)
316
- export function jsx(
317
- tag: string,
318
- attrs: MoonBitTuple<string, unknown>[],
319
- children: Node[]
320
- ): Node;
321
- export function jsxs(
322
- tag: string,
323
- attrs: MoonBitTuple<string, unknown>[],
324
- children: Node[]
325
- ): Node;
326
- /** Fragment function - returns children wrapped in a DocumentFragment */
327
- export function Fragment(children: Node[]): Node;
328
-
329
- /** Fragment symbol for JSX */
330
- export const FragmentSymbol: unique symbol;
331
-
332
- // Element creation (low-level)
333
- export function createElement(
334
- tag: string,
335
- attrs: MoonBitTuple<string, unknown>[],
336
- children: Node[]
337
- ): Node;
338
-
339
- // ============================================================================
340
- // Context API
341
- // ============================================================================
342
-
343
- /** Opaque Context type */
344
- export interface Context<T> {
345
- readonly __brand: unique symbol;
346
- readonly __type: T;
347
- }
348
-
349
- /** Create a new context with a default value */
350
- export function createContext<T>(defaultValue: T): Context<T>;
351
-
352
- /**
353
- * Provide a context value for the current Owner scope and its descendants.
354
- * Context values are Owner-based (component-tree-scoped), similar to SolidJS.
355
- */
356
- export function provide<T, R>(ctx: Context<T>, value: T, fn: () => R): R;
357
-
358
- /** Use a context value - returns the current provided value or default */
359
- export function useContext<T>(ctx: Context<T>): T;
360
-
361
- // ============================================================================
362
- // Resource API (SolidJS-style)
363
- // ============================================================================
364
-
365
- /** Resource state */
366
- export type ResourceState = "unresolved" | "pending" | "ready" | "errored";
367
-
368
- /** Resource accessor with properties */
369
- export interface ResourceAccessor<T> {
370
- (): T | undefined;
371
- readonly loading: boolean;
372
- readonly error: string | undefined;
373
- readonly state: ResourceState;
374
- readonly latest: T | undefined;
375
- }
376
-
377
- /** Resource actions */
378
- export interface ResourceActions {
379
- refetch: () => void;
380
- }
381
-
382
- /**
383
- * Create a Resource from a callback-based fetcher (SolidJS-style)
384
- * @example
385
- * const [data, { refetch }] = createResource((resolve, reject) => {
386
- * fetch('/api').then(r => r.json()).then(resolve).catch(e => reject(e.message));
387
- * });
388
- * data(); // value or undefined
389
- * data.loading; // boolean
390
- * data.error; // string or undefined
391
- */
392
- export function createResource<T>(
393
- fetcher: (resolve: (value: T) => void, reject: (error: string) => void) => void
394
- ): [ResourceAccessor<T>, ResourceActions];
395
-
396
- /**
397
- * Create a deferred Resource (SolidJS-style)
398
- * Returns [accessor, resolve, reject]
399
- */
400
- export function createDeferred<T>(): [
401
- ResourceAccessor<T>,
402
- (value: T) => void,
403
- (error: string) => void
404
- ];
405
-
406
- // Low-level resource helpers
407
- export function resourceGet<T>(resource: any): any;
408
- export function resourcePeek<T>(resource: any): any;
409
- export function resourceRefetch<T>(resource: any): void;
410
- export function resourceIsPending<T>(resource: any): boolean;
411
- export function resourceIsSuccess<T>(resource: any): boolean;
412
- export function resourceIsFailure<T>(resource: any): boolean;
413
- export function resourceValue<T>(resource: any): T | undefined;
414
- export function resourceError<T>(resource: any): string | undefined;
415
- export function stateIsPending<T>(state: any): boolean;
416
- export function stateIsSuccess<T>(state: any): boolean;
417
- export function stateIsFailure<T>(state: any): boolean;
418
- export function stateValue<T>(state: any): T | undefined;
419
- export function stateError<T>(state: any): string | undefined;
420
-
421
- // ============================================================================
422
- // Timer utilities
423
- // ============================================================================
424
-
425
- /** Debounce a signal */
426
- export function debounced<T>(signal: Signal<T>, delayMs: number): Signal<T>;
427
-
428
- // ============================================================================
429
- // Store API (SolidJS-style)
430
- // ============================================================================
431
-
432
- /** Path segment type for setState */
433
- type PathSegment = string | number;
434
-
435
- /** Store setter function type */
436
- export interface SetStoreFunction<T> {
437
- /** Update value at path */
438
- <K1 extends keyof T>(key1: K1, value: T[K1] | ((prev: T[K1]) => T[K1])): void;
439
- <K1 extends keyof T, K2 extends keyof T[K1]>(
440
- key1: K1,
441
- key2: K2,
442
- value: T[K1][K2] | ((prev: T[K1][K2]) => T[K1][K2])
443
- ): void;
444
- <K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(
445
- key1: K1,
446
- key2: K2,
447
- key3: K3,
448
- value: T[K1][K2][K3] | ((prev: T[K1][K2][K3]) => T[K1][K2][K3])
449
- ): void;
450
- /** Merge object at root */
451
- (value: Partial<T>): void;
452
- /** Generic path-based update */
453
- (...args: [...PathSegment[], unknown]): void;
454
- }
455
-
456
- /** Store tuple type */
457
- export type Store<T> = [T, SetStoreFunction<T>];
458
-
459
- /**
460
- * Creates a reactive store with nested property tracking (SolidJS-style)
461
- * @example
462
- * const [state, setState] = createStore({ count: 0, user: { name: "John" } });
463
- *
464
- * // Read (reactive - tracks dependencies)
465
- * state.count
466
- * state.user.name
467
- *
468
- * // Update by path
469
- * setState("count", 1);
470
- * setState("user", "name", "Jane");
471
- *
472
- * // Functional update
473
- * setState("count", c => c + 1);
474
- *
475
- * // Object merge at path
476
- * setState("user", { name: "Jane", age: 30 });
477
- */
478
- export function createStore<T extends object>(initialValue: T): Store<T>;
479
-
480
- /**
481
- * Produce helper for immer-style mutations (SolidJS-style)
482
- * @example
483
- * setState("user", produce(user => { user.name = "Jane"; }));
484
- */
485
- export function produce<T>(fn: (draft: T) => void): (state: T) => T;
486
-
487
- /**
488
- * Reconcile helper for efficient array/object updates (SolidJS-style)
489
- * Replaces the entire value at the path
490
- * @example
491
- * setState("items", reconcile(newItems));
492
- */
493
- export function reconcile<T>(value: T): (state: T) => T;
494
-
495
- // ============================================================================
496
- // Router API
497
- // ============================================================================
498
-
499
- /** Route definition - Page route */
500
- export interface PageRoute {
501
- readonly $tag: 0;
502
- readonly path: string;
503
- readonly component: string;
504
- readonly title: string;
505
- readonly meta: MoonBitTuple<string, string>[];
506
- }
507
-
508
- /** Route definition union type */
509
- export type Routes = PageRoute;
510
-
511
- export function routePage(path: string, component: string): Routes;
512
- export function routePageTitled(path: string, component: string, title: string): Routes;
513
- export function routePageFull(path: string, component: string, title: string, meta: MoonBitTuple<string, string>[]): Routes;
514
-
515
- /** Opaque BrowserRouter type */
516
- export interface BrowserRouter {
517
- readonly __brand: unique symbol;
518
- }
519
-
520
- /** Compiled route info */
521
- export interface CompiledRoute {
522
- readonly pattern: string;
523
- readonly param_names: string[];
524
- readonly component: string;
525
- readonly layouts: string[];
526
- }
527
-
528
- /** Route match result */
529
- export interface RoutesMatch {
530
- readonly route: CompiledRoute;
531
- readonly params: MoonBitTuple<string, string>[];
532
- readonly query: MoonBitTuple<string, string>[];
533
- readonly path: string;
534
- }
535
-
536
- export function createRouter(routes: Routes[], base?: string): BrowserRouter;
537
- export function routerNavigate(router: BrowserRouter, path: string): void;
538
- export function routerReplace(router: BrowserRouter, path: string): void;
539
- export function routerGetPath(router: BrowserRouter): string;
540
- export function routerGetMatch(router: BrowserRouter): RoutesMatch | undefined;
541
- export function routerGetBase(router: BrowserRouter): string;
542
-
543
- // ============================================================================
544
- // Legacy API (for backwards compatibility)
545
- // ============================================================================
546
-
547
- /** @deprecated Use createSignal()[0] instead */
548
- export function get<T>(signal: any): T;
549
- /** @deprecated Use createSignal()[1] instead */
550
- export function set<T>(signal: any, value: T): void;
551
- /** @deprecated Use createSignal()[1] with function instead */
552
- export function update<T>(signal: any, fn: (current: T) => T): void;
553
- /** @deprecated */
554
- export function peek<T>(signal: any): T;
555
- /** @deprecated */
556
- export function subscribe<T>(signal: any, callback: (value: T) => void): () => void;
557
- /** @deprecated */
558
- export function map<T, U>(signal: any, fn: (value: T) => U): () => U;
559
- /** @deprecated */
560
- export function combine<A, B, R>(a: any, b: any, fn: (a: A, b: B) => R): () => R;
561
- /** @deprecated Use createEffect instead */
562
- export function effect(fn: () => void): () => void;
563
- /** @deprecated Use untrack instead */
564
- export function runUntracked<T>(fn: () => T): T;