@manyducks.co/dolla 2.0.0-alpha.4 → 2.0.0-alpha.41

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.
Files changed (74) hide show
  1. package/README.md +31 -964
  2. package/dist/core/context.d.ts +53 -0
  3. package/dist/{modules → core}/dolla.d.ts +43 -26
  4. package/dist/core/markup.d.ts +90 -0
  5. package/dist/core/nodes/dom.d.ts +13 -0
  6. package/dist/core/nodes/dynamic.d.ts +28 -0
  7. package/dist/core/nodes/html.d.ts +33 -0
  8. package/dist/core/nodes/list.d.ts +28 -0
  9. package/dist/core/nodes/outlet.d.ts +19 -0
  10. package/dist/core/nodes/portal.d.ts +22 -0
  11. package/dist/core/nodes/view.d.ts +78 -0
  12. package/dist/core/ref.d.ts +28 -0
  13. package/dist/core/signals.d.ts +127 -0
  14. package/dist/core/store.d.ts +52 -0
  15. package/dist/core/symbols.d.ts +4 -0
  16. package/dist/{views → core/views}/passthrough.d.ts +1 -1
  17. package/dist/{modules/http.d.ts → http/index.d.ts} +3 -5
  18. package/dist/index.d.ts +14 -11
  19. package/dist/index.js +986 -1216
  20. package/dist/index.js.map +1 -1
  21. package/dist/jsx-dev-runtime.d.ts +2 -2
  22. package/dist/jsx-dev-runtime.js +2 -2
  23. package/dist/jsx-dev-runtime.js.map +1 -1
  24. package/dist/jsx-runtime.d.ts +3 -3
  25. package/dist/jsx-runtime.js +2 -2
  26. package/dist/jsx-runtime.js.map +1 -1
  27. package/dist/markup-DkQI155j.js +1447 -0
  28. package/dist/markup-DkQI155j.js.map +1 -0
  29. package/dist/{modules/router.d.ts → router/index.d.ts} +37 -48
  30. package/dist/router/router.utils.test.d.ts +1 -0
  31. package/dist/translate/index.d.ts +133 -0
  32. package/dist/typeChecking.d.ts +2 -98
  33. package/dist/typeChecking.test.d.ts +1 -0
  34. package/dist/types.d.ts +12 -14
  35. package/dist/utils.d.ts +18 -3
  36. package/docs/http.md +29 -0
  37. package/docs/i18n.md +38 -0
  38. package/docs/index.md +10 -0
  39. package/docs/router.md +80 -0
  40. package/docs/setup.md +31 -0
  41. package/docs/signals.md +149 -0
  42. package/docs/state.md +141 -0
  43. package/docs/stores.md +62 -0
  44. package/docs/views.md +208 -0
  45. package/index.d.ts +2 -2
  46. package/notes/TODO.md +6 -0
  47. package/notes/atomic.md +209 -0
  48. package/notes/context-routes.md +56 -0
  49. package/notes/elimination.md +33 -0
  50. package/notes/readme-scratch.md +260 -0
  51. package/notes/route-middleware.md +42 -0
  52. package/notes/scratch.md +330 -7
  53. package/notes/stores.md +53 -0
  54. package/package.json +14 -10
  55. package/vite.config.js +5 -10
  56. package/build.js +0 -34
  57. package/dist/markup.d.ts +0 -100
  58. package/dist/modules/language.d.ts +0 -41
  59. package/dist/modules/render.d.ts +0 -17
  60. package/dist/nodes/cond.d.ts +0 -26
  61. package/dist/nodes/html.d.ts +0 -31
  62. package/dist/nodes/observer.d.ts +0 -29
  63. package/dist/nodes/outlet.d.ts +0 -22
  64. package/dist/nodes/portal.d.ts +0 -19
  65. package/dist/nodes/repeat.d.ts +0 -34
  66. package/dist/nodes/text.d.ts +0 -19
  67. package/dist/passthrough-BSLd3foL.js +0 -1245
  68. package/dist/passthrough-BSLd3foL.js.map +0 -1
  69. package/dist/signals.d.ts +0 -101
  70. package/dist/view.d.ts +0 -50
  71. package/tests/signals.test.js +0 -135
  72. /package/dist/{routing.test.d.ts → core/signals.test.d.ts} +0 -0
  73. /package/dist/{views → core/views}/default-crash-view.d.ts +0 -0
  74. /package/dist/{routing.d.ts → router/router.utils.d.ts} +0 -0
@@ -0,0 +1,53 @@
1
+ import type { Dolla } from "./dolla";
2
+ import type { Store, StoreFunction } from "./store";
3
+ export interface ElementContext {
4
+ /**
5
+ * The root Dolla instance this element belongs to.
6
+ */
7
+ root: Dolla;
8
+ /**
9
+ * Stores attached to this context.
10
+ */
11
+ stores: Map<StoreFunction<any, any>, Store<any, any>>;
12
+ /**
13
+ * A reference to the parent context.
14
+ */
15
+ parent?: ElementContext;
16
+ /**
17
+ * Whether to create DOM nodes in the SVG namespace. An `<svg>` element will set this to true and pass it down to children.
18
+ */
19
+ isSVG?: boolean;
20
+ /**
21
+ * The name of the nearest parent view.
22
+ */
23
+ viewName?: string;
24
+ }
25
+ export interface ComponentContext {
26
+ /**
27
+ * A name for debugging purposes. Prepended to log messages.
28
+ */
29
+ name: string;
30
+ }
31
+ /**
32
+ * A context capable of providing stores.
33
+ */
34
+ export interface StoreProviderContext {
35
+ /**
36
+ * Attaches a new store to this context and returns it.
37
+ */
38
+ provide<Value>(store: StoreFunction<{}, Value>): Value;
39
+ /**
40
+ * Attaches a new store to this context and returns it.
41
+ */
42
+ provide<Value>(store: StoreFunction<undefined, Value>): Value;
43
+ /**
44
+ * Attaches a new store to this context and returns it.
45
+ */
46
+ provide<Options, Value>(store: StoreFunction<Options, Value>, options: Options): Value;
47
+ }
48
+ export interface StoreConsumerContext {
49
+ /**
50
+ * Gets the closest instance of a store. Throws an error if the store isn't provided higher in the tree.
51
+ */
52
+ get<Value>(store: StoreFunction<any, Value>): Value;
53
+ }
@@ -1,11 +1,11 @@
1
- import { createRef, isRef, MarkupNode, type Markup } from "../markup.js";
2
- import { createSettableSignal, createSignal, derive, designalify, signalify, toSettableSignal, watch, type Signal } from "../signals.js";
3
- import { type ViewFunction, type ViewNode } from "../view.js";
4
- import { type CrashViewProps } from "../views/default-crash-view.js";
5
- import { HTTP } from "./http.js";
6
- import { Language } from "./language.js";
7
- import { Render } from "./render.js";
8
- import { Router } from "./router.js";
1
+ import { HTTP } from "../http/index.js";
2
+ import { type Router } from "../router/index.js";
3
+ import { I18n } from "../translate/index.js";
4
+ import type { StoreConsumerContext, StoreProviderContext } from "./context.js";
5
+ import { type Markup, type MarkupElement } from "./markup.js";
6
+ import { type ViewElement, type ViewFunction } from "./nodes/view.js";
7
+ import { StoreFunction } from "./store.js";
8
+ import { type CrashViewProps } from "./views/default-crash-view.js";
9
9
  export type Environment = "development" | "production";
10
10
  /**
11
11
  * Log type toggles. Each message category can be turned on or off or enabled only in a specific environment.
@@ -22,6 +22,7 @@ export interface Logger {
22
22
  warn(...args: any[]): void;
23
23
  error(...args: any[]): void;
24
24
  crash(error: Error): void;
25
+ setName(name: string): Logger;
25
26
  }
26
27
  export interface LoggerErrorContext {
27
28
  error: Error;
@@ -38,22 +39,11 @@ export type LoggerOptions = {
38
39
  */
39
40
  uid?: string;
40
41
  };
41
- export declare class Dolla {
42
+ export declare class Dolla implements StoreProviderContext, StoreConsumerContext {
42
43
  #private;
43
44
  readonly http: HTTP;
44
- readonly language: Language;
45
- readonly render: Render;
46
- readonly router: Router;
45
+ readonly i18n: I18n;
47
46
  constructor();
48
- createSignal: typeof createSignal;
49
- createSettableSignal: typeof createSettableSignal;
50
- toSettableSignal: typeof toSettableSignal;
51
- signalify: typeof signalify;
52
- designalify: typeof designalify;
53
- derive: typeof derive;
54
- watch: typeof watch;
55
- createRef: typeof createRef;
56
- isRef: typeof isRef;
57
47
  /**
58
48
  * True when the app is connected to a DOM node and displayed to the user.
59
49
  */
@@ -73,8 +63,34 @@ export declare class Dolla {
73
63
  * When a crash is reported the app will be unmounted and replaced with this crash page.
74
64
  */
75
65
  setCrashView(view: ViewFunction<CrashViewProps>): void;
76
- mount(selector: string, view?: ViewFunction<any>): Promise<void>;
77
- mount(element: HTMLElement, view?: ViewFunction<any>): Promise<void>;
66
+ /**
67
+ * Returns the HTMLElement Dolla is mounted to. This will return undefined until Dolla.mount() is called.
68
+ */
69
+ getRootElement(): Element | undefined;
70
+ /**
71
+ * Returns the top level view Dolla is rendering inside the root element. This will return undefined until Dolla.mount() is called.
72
+ */
73
+ getRootView(): ViewElement | undefined;
74
+ /**
75
+ * Attaches a new store to this context.
76
+ */
77
+ provide<Value>(store: StoreFunction<{}, Value>): Value;
78
+ /**
79
+ * Attaches a new store to this context.
80
+ */
81
+ provide<Value>(store: StoreFunction<undefined, Value>): Value;
82
+ /**
83
+ * Attaches a new store to this context.
84
+ */
85
+ provide<Options, Value>(store: StoreFunction<Options, Value>, options: Options): Value;
86
+ /**
87
+ * Gets the nearest instance of a store. Throws an error if the store isn't provided higher in the tree.
88
+ */
89
+ get<Value>(store: StoreFunction<any, Value>): Value;
90
+ mount(selector: string, router: Router): Promise<void>;
91
+ mount(selector: string, view: ViewFunction<any>): Promise<void>;
92
+ mount(element: Element, router: Router): Promise<void>;
93
+ mount(element: Element, view: ViewFunction<any>): Promise<void>;
78
94
  unmount(): Promise<void>;
79
95
  /**
80
96
  * Registers a `callback` to run after `Dolla.mount` is called, before the app is mounted. If `callback` returns a Promise,
@@ -99,13 +115,14 @@ export declare class Dolla {
99
115
  */
100
116
  setLoggles(options: Partial<Loggles>): void;
101
117
  setLogFilter(filter: string | RegExp): void;
102
- createLogger(name: string | Signal<string>, options?: LoggerOptions): Logger;
118
+ createLogger(name: string, options?: LoggerOptions): Logger;
103
119
  /**
104
120
  *
105
121
  */
106
- constructView<P>(view: ViewFunction<P>, props: P, children?: Markup[]): ViewNode;
122
+ constructView<P>(view: ViewFunction<P>, props: P, children?: Markup[]): ViewElement;
107
123
  /**
108
124
  *
109
125
  */
110
- constructMarkup(markup: Markup | Markup[]): MarkupNode;
126
+ constructMarkup(markup: Markup | Markup[]): MarkupElement;
111
127
  }
128
+ export declare function getDefaultConsole(): Console | undefined;
@@ -0,0 +1,90 @@
1
+ import type { Renderable } from "../types.js";
2
+ import type { ElementContext } from "./context.js";
3
+ import { type ViewContext, type ViewFunction, type ViewResult } from "./nodes/view.js";
4
+ import { MaybeReactive, type Reactive } from "./signals.js";
5
+ /**
6
+ * Markup is a set of element metadata that hasn't been constructed into a MarkupElement yet.
7
+ */
8
+ export interface Markup {
9
+ /**
10
+ * In the case of a view, type will be the View function itself. It can also hold an identifier for special nodes like "$cond", "$repeat", etc.
11
+ * DOM nodes can be created by name, such as HTML elements like "div", "ul" or "span", SVG elements like ""
12
+ */
13
+ type: string | ViewFunction<any>;
14
+ /**
15
+ * Data that will be passed to a new MarkupElement instance when it is constructed.
16
+ */
17
+ props?: Record<string, any>;
18
+ /**
19
+ *
20
+ */
21
+ children?: Markup[];
22
+ }
23
+ /**
24
+ * A DOM node that has been constructed from a Markup object.
25
+ */
26
+ export interface MarkupElement {
27
+ readonly node?: Node;
28
+ readonly isMounted: boolean;
29
+ mount(parent: Node, after?: Node): void;
30
+ /**
31
+ * Disconnect from the DOM and clean up. If parentIsUnmounting, DOM operations are skipped.
32
+ * parentIsUnmounting is set for all children by HTML nodes when they unmount.
33
+ */
34
+ unmount(parentIsUnmounting?: boolean): void;
35
+ }
36
+ export declare function isMarkup(value: any): value is Markup;
37
+ export declare function isMarkupElement(value: any): value is MarkupElement;
38
+ export declare function toMarkup(renderables: Renderable | Renderable[]): Markup[];
39
+ export interface MarkupAttributes {
40
+ $text: {
41
+ value: any;
42
+ };
43
+ $list: {
44
+ items: Reactive<any[]>;
45
+ keyFn: (value: any, index: number) => string | number | symbol;
46
+ renderFn: (item: Reactive<any>, index: Reactive<number>, ctx: ViewContext) => ViewResult;
47
+ };
48
+ $dynamic: {
49
+ source: Reactive<Renderable>;
50
+ };
51
+ $outlet: {
52
+ children: MaybeReactive<MarkupElement[]>;
53
+ };
54
+ $node: {
55
+ value: Node;
56
+ };
57
+ $portal: {
58
+ content: Renderable;
59
+ parent: Node;
60
+ };
61
+ [tag: string]: Record<string, any>;
62
+ }
63
+ export declare function createMarkup<T extends keyof MarkupAttributes>(type: T, attributes: MarkupAttributes[T], ...children: Renderable[]): Markup;
64
+ export declare function createMarkup<I>(type: ViewFunction<I>, attributes?: I, ...children: Renderable[]): Markup;
65
+ /**
66
+ * Generate markup with HTML in a tagged template literal.
67
+ */
68
+ export declare const html: (strings: TemplateStringsArray, ...values: any[]) => Markup | Markup[];
69
+ /**
70
+ * Displays content conditionally. When `condition` holds a truthy value, `thenContent` is displayed; when `condition` holds a falsy value, `elseContent` is displayed.
71
+ */
72
+ export declare function cond(condition: MaybeReactive<any>, thenContent?: Renderable, elseContent?: Renderable): Markup;
73
+ /**
74
+ * Calls `renderFn` for each item in `items`. Dynamically adds and removes views as items change.
75
+ * The result of `keyFn` is used to compare items and decide if item was added, removed or updated.
76
+ */
77
+ export declare function list<T>(items: MaybeReactive<T[]>, keyFn: (value: T, index: number) => string | number | symbol, renderFn: (item: Reactive<T>, index: Reactive<number>, ctx: ViewContext) => ViewResult): Markup;
78
+ /**
79
+ * Renders `content` into a `parent` node anywhere in the page, rather than its usual position in the view.
80
+ */
81
+ export declare function portal(parent: Node, content: Renderable): Markup;
82
+ /**
83
+ * Construct Markup metadata into a set of MarkupElements.
84
+ */
85
+ export declare function constructMarkup(elementContext: ElementContext, markup: Markup | Markup[]): MarkupElement[];
86
+ /**
87
+ * Combines one or more MarkupElements into a single MarkupElement.
88
+ */
89
+ export declare function groupElements(elements: MarkupElement[]): MarkupElement;
90
+ export declare function isRenderable(value: unknown): value is Renderable;
@@ -0,0 +1,13 @@
1
+ import type { MarkupElement } from "../markup";
2
+ import { IS_MARKUP_ELEMENT } from "../symbols";
3
+ /**
4
+ * Wraps any plain DOM node in a MarkupElement interface.
5
+ */
6
+ export declare class DOMNode implements MarkupElement {
7
+ [IS_MARKUP_ELEMENT]: boolean;
8
+ node: Node;
9
+ get isMounted(): boolean;
10
+ constructor(node: Node);
11
+ mount(parent: Node, after?: Node): void;
12
+ unmount(parentIsUnmounting?: boolean): void;
13
+ }
@@ -0,0 +1,28 @@
1
+ import type { Renderable } from "../../types.js";
2
+ import type { ElementContext } from "../context.js";
3
+ import { type MarkupElement } from "../markup.js";
4
+ import { type Reactive } from "../signals.js";
5
+ import { IS_MARKUP_ELEMENT } from "../symbols.js";
6
+ interface DynamicOptions {
7
+ source: Reactive<Renderable>;
8
+ elementContext: ElementContext;
9
+ }
10
+ /**
11
+ * Displays dynamic children without a parent element.
12
+ * Renders a Reactive value via a render function.
13
+ */
14
+ export declare class Dynamic implements MarkupElement {
15
+ [IS_MARKUP_ELEMENT]: boolean;
16
+ node: Text;
17
+ private children;
18
+ private elementContext;
19
+ private source;
20
+ private unsubscribe?;
21
+ get isMounted(): boolean;
22
+ constructor(options: DynamicOptions);
23
+ mount(parent: Node, after?: Node): void;
24
+ unmount(parentIsUnmounting?: boolean): void;
25
+ cleanup(parentIsUnmounting: boolean): void;
26
+ update(children: Renderable[]): void;
27
+ }
28
+ export {};
@@ -0,0 +1,33 @@
1
+ import { type ElementContext } from "../context.js";
2
+ import { type Markup, type MarkupElement } from "../markup.js";
3
+ import { IS_MARKUP_ELEMENT } from "../symbols.js";
4
+ type HTMLOptions = {
5
+ elementContext: ElementContext;
6
+ tag: string;
7
+ props: Record<string, any>;
8
+ children?: Markup[];
9
+ };
10
+ export declare class HTML implements MarkupElement {
11
+ [IS_MARKUP_ELEMENT]: boolean;
12
+ node: HTMLElement | SVGElement;
13
+ private props;
14
+ private childMarkup;
15
+ private children;
16
+ private unsubscribers;
17
+ private elementContext;
18
+ private ref?;
19
+ private canClickAway;
20
+ get isMounted(): boolean;
21
+ constructor({ tag, props, children, elementContext }: HTMLOptions);
22
+ mount(parent: Node, after?: Node): void;
23
+ unmount(parentIsUnmounting?: boolean): void;
24
+ private attachProp;
25
+ private applyProps;
26
+ private applyStyles;
27
+ private applyClasses;
28
+ }
29
+ /**
30
+ * Converts a camelCase string to kebab-case.
31
+ */
32
+ export declare function camelToKebab(value: string): string;
33
+ export {};
@@ -0,0 +1,28 @@
1
+ import { type ElementContext } from "../context.js";
2
+ import { type MarkupElement } from "../markup.js";
3
+ import { type Reactive } from "../signals.js";
4
+ import { IS_MARKUP_ELEMENT } from "../symbols.js";
5
+ import { type ViewContext, type ViewResult } from "./view.js";
6
+ interface ListOptions<T> {
7
+ elementContext: ElementContext;
8
+ items: Reactive<T[]>;
9
+ keyFn: (item: T, index: number) => string | number | symbol;
10
+ renderFn: (item: Reactive<T>, index: Reactive<number>, ctx: ViewContext) => ViewResult;
11
+ }
12
+ export declare class List<T> implements MarkupElement {
13
+ [IS_MARKUP_ELEMENT]: boolean;
14
+ node: Text;
15
+ private items;
16
+ private unsubscribe;
17
+ private connectedItems;
18
+ private elementContext;
19
+ private renderFn;
20
+ private keyFn;
21
+ get isMounted(): boolean;
22
+ constructor({ elementContext, items, renderFn, keyFn }: ListOptions<T>);
23
+ mount(parent: Node, after?: Node): void;
24
+ unmount(parentIsUnmounting?: boolean): void;
25
+ private _cleanup;
26
+ private _update;
27
+ }
28
+ export {};
@@ -0,0 +1,19 @@
1
+ import { type MarkupElement } from "../markup.js";
2
+ import { type MaybeReactive } from "../signals.js";
3
+ import { IS_MARKUP_ELEMENT } from "../symbols.js";
4
+ /**
5
+ * Manages several MarkupElements as one.
6
+ */
7
+ export declare class Outlet implements MarkupElement {
8
+ [IS_MARKUP_ELEMENT]: boolean;
9
+ node: Text;
10
+ isMounted: boolean;
11
+ private source;
12
+ private elements;
13
+ private unsubscribe?;
14
+ constructor(source: MaybeReactive<MarkupElement[]>);
15
+ mount(parent: Node, after?: Node | undefined): void;
16
+ unmount(parentIsUnmounting?: boolean): void;
17
+ private cleanup;
18
+ private update;
19
+ }
@@ -0,0 +1,22 @@
1
+ import type { Renderable } from "../../types.js";
2
+ import type { ElementContext } from "../context.js";
3
+ import { type MarkupElement } from "../markup.js";
4
+ import { IS_MARKUP_ELEMENT } from "../symbols.js";
5
+ interface PortalConfig {
6
+ content: Renderable;
7
+ parent: Node;
8
+ elementContext: ElementContext;
9
+ }
10
+ /**
11
+ * Renders content into a specified parent node.
12
+ */
13
+ export declare class Portal implements MarkupElement {
14
+ [IS_MARKUP_ELEMENT]: boolean;
15
+ private config;
16
+ private element?;
17
+ get isMounted(): boolean;
18
+ constructor(config: PortalConfig);
19
+ mount(_parent: Node, _after?: Node): void;
20
+ unmount(parentIsUnmounting?: boolean): void;
21
+ }
22
+ export {};
@@ -0,0 +1,78 @@
1
+ import type { ComponentContext, ElementContext, StoreConsumerContext, StoreProviderContext } from "../context.js";
2
+ import type { Logger } from "../dolla.js";
3
+ import { type Markup, type MarkupElement } from "../markup.js";
4
+ import { type EffectCallback, type Reactive, type UnsubscribeFunction } from "../signals.js";
5
+ import { IS_MARKUP_ELEMENT } from "../symbols.js";
6
+ /**
7
+ * Any valid value that a View can return.
8
+ */
9
+ export type ViewResult = Node | Reactive<any> | Markup | Markup[] | null;
10
+ export type ViewFunction<P> = (this: ViewContext, props: P, context: ViewContext) => ViewResult;
11
+ /**
12
+ * A view that has been constructed into DOM nodes.
13
+ */
14
+ export interface ViewElement extends MarkupElement {
15
+ /**
16
+ * Take a ViewFunction and render it as a child of this view.
17
+ */
18
+ setChildView(view: ViewFunction<{}>): ViewElement;
19
+ }
20
+ export interface ViewContext extends Omit<Logger, "setName">, ComponentContext, StoreProviderContext, StoreConsumerContext {
21
+ /**
22
+ * An ID unique to this view.
23
+ */
24
+ readonly uid: string;
25
+ /**
26
+ * True while this view is connected to the DOM.
27
+ */
28
+ readonly isMounted: boolean;
29
+ /**
30
+ * Registers a callback to run just before this view is mounted. DOM nodes are not yet attached to the page.
31
+ */
32
+ beforeMount(callback: () => void): void;
33
+ /**
34
+ * Registers a callback to run just after this view is mounted.
35
+ */
36
+ onMount(callback: () => void): void;
37
+ /**
38
+ * Registers a callback to run just before this view is unmounted. DOM nodes are still attached to the page.
39
+ */
40
+ beforeUnmount(callback: () => void): void;
41
+ /**
42
+ * Registers a callback to run just after this view is unmounted.
43
+ */
44
+ onUnmount(callback: () => void): void;
45
+ /**
46
+ * Passes a getter function to `callback` that will track reactive states and return their current values.
47
+ * Callback will be run each time a tracked state gets a new value.
48
+ */
49
+ effect(callback: EffectCallback): UnsubscribeFunction;
50
+ /**
51
+ * Returns a Markup element that displays this view's children.
52
+ */
53
+ outlet(): Markup;
54
+ }
55
+ export declare class View<P> implements ViewElement {
56
+ [IS_MARKUP_ELEMENT]: boolean;
57
+ uniqueId: string;
58
+ elementContext: ElementContext;
59
+ logger: Logger;
60
+ props: P;
61
+ fn: ViewFunction<P>;
62
+ element?: MarkupElement;
63
+ childMarkup: Markup[];
64
+ children: import("../signals.js").Atom<MarkupElement[]>;
65
+ lifecycleListeners: {
66
+ beforeMount: (() => any)[];
67
+ mount: (() => any)[];
68
+ beforeUnmount: (() => any)[];
69
+ unmount: (() => any)[];
70
+ };
71
+ constructor(elementContext: ElementContext, fn: ViewFunction<P>, props: P, children?: Markup[]);
72
+ get node(): Node;
73
+ isMounted: boolean;
74
+ mount(parent: Node, after?: Node): void;
75
+ unmount(parentIsUnmounting?: boolean): void;
76
+ setChildView(fn: ViewFunction<{}>): View<{}>;
77
+ private _initialize;
78
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A `Ref` is a function that stores a value when called with a single argument,
3
+ * and returns the most recently stored value when called with no arguments.
4
+ */
5
+ export interface Ref<T> {
6
+ /**
7
+ * Get: returns the current value stored in the ref (or undefined).
8
+ */
9
+ (): T | undefined;
10
+ /**
11
+ * Set: stores a new `value` in the ref.
12
+ */
13
+ <T>(value: T | undefined): void;
14
+ }
15
+ /**
16
+ * A Ref is a function that returns the last argument it was called with.
17
+ * Calling it with no arguments will simply return the latest value.
18
+ * Calling it with an argument will store that value and immediately return it.
19
+ *
20
+ * @param value - An (optional) initial value to store.
21
+ *
22
+ * @example
23
+ * const number = ref(5);
24
+ * number(); // 5
25
+ * number(500);
26
+ * number(); // 500
27
+ */
28
+ export declare function ref<T>(value?: T): Ref<T>;
@@ -0,0 +1,127 @@
1
+ import { type Dependency, type Subscriber } from "alien-signals";
2
+ export interface Effect extends Subscriber, Dependency {
3
+ fn(): void;
4
+ }
5
+ export interface Computed<T = any> extends Signal<T | undefined>, Subscriber {
6
+ getter: (cachedValue?: T) => T;
7
+ equals: EqualityFunction<T>;
8
+ }
9
+ export interface Signal<T = any> extends Dependency {
10
+ currentValue: T;
11
+ }
12
+ /**
13
+ * A readable reactive state object.
14
+ */
15
+ export interface Reactive<T> {
16
+ /**
17
+ * The current value.
18
+ */
19
+ readonly value: T;
20
+ }
21
+ export type MaybeReactive<T> = Reactive<T> | T;
22
+ export type UnsubscribeFunction = () => void;
23
+ export declare function pauseTracking(): void;
24
+ export declare function resumeTracking(): void;
25
+ /**
26
+ * A function to compare the current and next values. Returning `true` means the value has changed.
27
+ */
28
+ export type EqualityFunction<T> = (current: T, next: T) => boolean;
29
+ export interface ReactiveOptions<T> {
30
+ /**
31
+ * A label for debugging purposes.
32
+ */
33
+ name?: string;
34
+ /**
35
+ * A function to compare the current and next values. Returning `true` means the value has changed.
36
+ */
37
+ equals?: EqualityFunction<T>;
38
+ }
39
+ export declare class Atom<T> implements Reactive<T> {
40
+ #private;
41
+ name?: string;
42
+ constructor(signal: Signal<T>, options?: ReactiveOptions<T>);
43
+ get value(): T;
44
+ set value(next: T);
45
+ }
46
+ /**
47
+ * Determines if a value is reactive.
48
+ */
49
+ export declare function isReactive<T>(value: any): value is Reactive<T>;
50
+ /**
51
+ * Creates a simple reactive container that stores a value.
52
+ * Atom values can be read and updated with the `value` property
53
+ *
54
+ * @example
55
+ * const count = atom(1);
56
+ * count.value++;
57
+ * count.value; // 2
58
+ */
59
+ export declare function atom<T>(): Atom<T | undefined>;
60
+ /**
61
+ * Creates a simple reactive container that stores a value.
62
+ * Atom values can be read and updated with the `value` property.
63
+ *
64
+ * @example
65
+ * const count = atom(1);
66
+ * count.value++;
67
+ * count.value; // 2
68
+ */
69
+ export declare function atom<T>(value: T, options?: ReactiveOptions<T>): Atom<T>;
70
+ /**
71
+ * Creates a simple reactive container that stores a value.
72
+ * Atom values can be read and updated with the `value` property.
73
+ *
74
+ * @example
75
+ * const count = atom(1);
76
+ * count.value++;
77
+ * count.value; // 2
78
+ */
79
+ export declare function atom<T>(value?: T, options?: ReactiveOptions<T>): Atom<T | undefined>;
80
+ type ComposeCallback<T> = (previousValue?: T) => MaybeReactive<T>;
81
+ /**
82
+ * Creates a reactive container that derives its value from other reactive values that it tracks.
83
+ *
84
+ * @example
85
+ * const count = atom(1);
86
+ * const doubled = compose(() => get(count) * 2);
87
+ */
88
+ export declare function compose<T>(fn: ComposeCallback<T>, options?: ReactiveOptions<T>): Reactive<T>;
89
+ /**
90
+ * Takes a new value to set, or a callback that receives the current value and returns a new value to set.
91
+ */
92
+ type Setter<T> = (next: T | ((current: T) => T)) => void;
93
+ export declare function set<T>(atom: Atom<T>): Setter<T>;
94
+ export declare function set<T>(atom: Atom<T>, next: T | ((current: T) => T)): void;
95
+ /**
96
+ * Returns the current value from a reactive _and track it_ if called in a `compose` or `effect` scope.
97
+ * If a non-reactive value is passed it will just be returned untracked.
98
+ *
99
+ * @example
100
+ * const count = atom(1);
101
+ * const value = get(count); // 1
102
+ *
103
+ * const value = get(5); // 5
104
+ */
105
+ export declare function get<T>(value: MaybeReactive<T>): T;
106
+ /**
107
+ * Returns the current value from a reactive (without tracking).
108
+ * If a non-reactive value is passed it will be returned.
109
+ *
110
+ * @example
111
+ * ctx.effect(() => {
112
+ * const doubled = get(count) * 2; // `count` will be tracked
113
+ *
114
+ * const doubled = peek(count) * 2; // `count` will NOT be tracked
115
+ * });
116
+ */
117
+ export declare function peek<T>(value: MaybeReactive<T>): T;
118
+ export type EffectCallback = () => void;
119
+ /**
120
+ * Creates a tracked scope that re-runs whenever the values of any tracked reactives changes.
121
+ * Reactives are tracked by accessing their `value` within the body of the function.
122
+ *
123
+ * NOTE: You must call the unsubscribe function to stop watching for changes.
124
+ * If you are using an effect inside a View or Store, use `ctx.effect` instead, which cleans up automatically when the component unmounts.
125
+ */
126
+ export declare function effect(fn: EffectCallback): UnsubscribeFunction;
127
+ export {};