@manyducks.co/dolla 2.0.0-alpha.1 → 2.0.0-alpha.11

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 (42) hide show
  1. package/README.md +196 -473
  2. package/dist/index.d.ts +10 -33
  3. package/dist/index.js +827 -708
  4. package/dist/index.js.map +1 -1
  5. package/dist/jsx-dev-runtime.d.ts +1 -1
  6. package/dist/jsx-dev-runtime.js +2 -2
  7. package/dist/jsx-dev-runtime.js.map +1 -1
  8. package/dist/jsx-runtime.d.ts +1 -1
  9. package/dist/jsx-runtime.js +2 -2
  10. package/dist/jsx-runtime.js.map +1 -1
  11. package/dist/markup.d.ts +37 -23
  12. package/dist/modules/dolla.d.ts +41 -17
  13. package/dist/modules/i18n.d.ts +93 -0
  14. package/dist/modules/router.d.ts +9 -10
  15. package/dist/nodes/cond.d.ts +9 -10
  16. package/dist/nodes/html.d.ts +14 -10
  17. package/dist/nodes/observer.d.ts +9 -10
  18. package/dist/nodes/outlet.d.ts +10 -11
  19. package/dist/nodes/portal.d.ts +6 -7
  20. package/dist/nodes/repeat.d.ts +15 -16
  21. package/dist/nodes/text.d.ts +8 -9
  22. package/dist/passthrough-Bu7iYKPr.js +1278 -0
  23. package/dist/passthrough-Bu7iYKPr.js.map +1 -0
  24. package/dist/state.d.ts +101 -0
  25. package/dist/types.d.ts +12 -12
  26. package/dist/view.d.ts +28 -7
  27. package/dist/views/default-crash-view.d.ts +18 -0
  28. package/dist/views/passthrough.d.ts +5 -0
  29. package/notes/context-vars.md +21 -0
  30. package/notes/readme-scratch.md +222 -0
  31. package/notes/route-middleware.md +42 -0
  32. package/notes/scratch.md +42 -5
  33. package/package.json +8 -12
  34. package/tests/{signals.test.js → state.test.js} +6 -6
  35. package/vite.config.js +1 -0
  36. package/dist/fragment-DHJiX0-a.js +0 -1241
  37. package/dist/fragment-DHJiX0-a.js.map +0 -1
  38. package/dist/modules/language.d.ts +0 -41
  39. package/dist/signals.d.ts +0 -101
  40. package/dist/views/default-crash-page.d.ts +0 -8
  41. package/dist/views/default-view.d.ts +0 -2
  42. package/dist/views/fragment.d.ts +0 -2
@@ -1,2 +1,2 @@
1
1
  export function jsxDEV(element: any, props: any, key: any, isStaticChildren: any, source: any, self: any): import("./markup.ts").Markup;
2
- export { Fragment } from "./views/fragment.ts";
2
+ export { Passthrough as Fragment } from "./views/passthrough.ts";
@@ -1,5 +1,5 @@
1
- import { j as s } from "./fragment-DHJiX0-a.js";
2
- import { F as m } from "./fragment-DHJiX0-a.js";
1
+ import { q as s } from "./passthrough-Bu7iYKPr.js";
2
+ import { P as m } from "./passthrough-Bu7iYKPr.js";
3
3
  function d(n, r, t, e, a, l) {
4
4
  const i = { ...o(["children", "key"], r) }, c = Array.isArray(r.children) ? r.children : [r.children];
5
5
  return s(n, i, ...c);
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-dev-runtime.js","sources":["../src/jsx-dev-runtime.js"],"sourcesContent":["import { createMarkup } from \"./markup.ts\";\nexport { Fragment } from \"./views/fragment.ts\";\n\nexport function jsxDEV(element, props, key, isStaticChildren, source, self) {\n const attributes = { ...omit([\"children\", \"key\"], props) };\n const children = Array.isArray(props.children) ? props.children : [props.children];\n\n return createMarkup(element, attributes, ...children);\n}\n\nfunction omit(keys, object) {\n const result = {};\n for (const key in object) {\n if (!keys.includes(key)) {\n result[key] = object[key];\n }\n }\n return result;\n}\n"],"names":["jsxDEV","element","props","key","isStaticChildren","source","self","attributes","omit","children","createMarkup","keys","object","result"],"mappings":";;AAGO,SAASA,EAAOC,GAASC,GAAOC,GAAKC,GAAkBC,GAAQC,GAAM;AAC1E,QAAMC,IAAa,EAAE,GAAGC,EAAK,CAAC,YAAY,KAAK,GAAGN,CAAK,EAAG,GACpDO,IAAW,MAAM,QAAQP,EAAM,QAAQ,IAAIA,EAAM,WAAW,CAACA,EAAM,QAAQ;AAEjF,SAAOQ,EAAaT,GAASM,GAAY,GAAGE,CAAQ;AACtD;AAEA,SAASD,EAAKG,GAAMC,GAAQ;AAC1B,QAAMC,IAAS,CAAE;AACjB,aAAWV,KAAOS;AAChB,IAAKD,EAAK,SAASR,CAAG,MACpBU,EAAOV,CAAG,IAAIS,EAAOT,CAAG;AAG5B,SAAOU;AACT;"}
1
+ {"version":3,"file":"jsx-dev-runtime.js","sources":["../src/jsx-dev-runtime.js"],"sourcesContent":["import { createMarkup } from \"./markup.ts\";\nexport { Passthrough as Fragment } from \"./views/passthrough.ts\";\n\nexport function jsxDEV(element, props, key, isStaticChildren, source, self) {\n const attributes = { ...omit([\"children\", \"key\"], props) };\n const children = Array.isArray(props.children) ? props.children : [props.children];\n\n return createMarkup(element, attributes, ...children);\n}\n\nfunction omit(keys, object) {\n const result = {};\n for (const key in object) {\n if (!keys.includes(key)) {\n result[key] = object[key];\n }\n }\n return result;\n}\n"],"names":["jsxDEV","element","props","key","isStaticChildren","source","self","attributes","omit","children","createMarkup","keys","object","result"],"mappings":";;AAGO,SAASA,EAAOC,GAASC,GAAOC,GAAKC,GAAkBC,GAAQC,GAAM;AAC1E,QAAMC,IAAa,EAAE,GAAGC,EAAK,CAAC,YAAY,KAAK,GAAGN,CAAK,EAAG,GACpDO,IAAW,MAAM,QAAQP,EAAM,QAAQ,IAAIA,EAAM,WAAW,CAACA,EAAM,QAAQ;AAEjF,SAAOQ,EAAaT,GAASM,GAAY,GAAGE,CAAQ;AACtD;AAEA,SAASD,EAAKG,GAAMC,GAAQ;AAC1B,QAAMC,IAAS,CAAE;AACjB,aAAWV,KAAOS;AAChB,IAAKD,EAAK,SAASR,CAAG,MACpBU,EAAOV,CAAG,IAAIS,EAAOT,CAAG;AAG5B,SAAOU;AACT;"}
@@ -6,4 +6,4 @@ export function jsx(element: any, props: any, key: any): import("./markup.ts").M
6
6
  * JSX function for elements with static children.
7
7
  */
8
8
  export function jsxs(element: any, props: any, key: any): import("./markup.ts").Markup;
9
- export { Fragment } from "./views/fragment.ts";
9
+ export { Passthrough as Fragment } from "./views/passthrough.ts";
@@ -1,5 +1,5 @@
1
- import { j as t } from "./fragment-DHJiX0-a.js";
2
- import { F as l } from "./fragment-DHJiX0-a.js";
1
+ import { q as t } from "./passthrough-Bu7iYKPr.js";
2
+ import { P as l } from "./passthrough-Bu7iYKPr.js";
3
3
  function d(n, e, r) {
4
4
  return t(n, e ? { ...u(["children", "key"], e) } : void 0, e.children);
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-runtime.js","sources":["../src/jsx-runtime.js"],"sourcesContent":["import { createMarkup } from \"./markup.ts\";\nexport { Fragment } from \"./views/fragment.ts\";\n\n/**\n * JSX function for elements with dynamic children.\n */\nexport function jsx(element, props, key) {\n return createMarkup(element, props ? { ...omit([\"children\", \"key\"], props) } : undefined, ...[props.children]);\n}\n\n/**\n * JSX function for elements with static children.\n */\nexport function jsxs(element, props, key) {\n return createMarkup(element, props ? { ...omit([\"children\", \"key\"], props) } : undefined, props.children);\n}\n\nfunction omit(keys, object) {\n const result = {};\n for (const key in object) {\n if (!keys.includes(key)) {\n result[key] = object[key];\n }\n }\n return result;\n}\n"],"names":["jsx","element","props","key","createMarkup","omit","jsxs","keys","object","result"],"mappings":";;AAMO,SAASA,EAAIC,GAASC,GAAOC,GAAK;AACvC,SAAOC,EAAaH,GAASC,IAAQ,EAAE,GAAGG,EAAK,CAAC,YAAY,KAAK,GAAGH,CAAK,EAAC,IAAK,QAAeA,EAAM,QAAS;AAC/G;AAKO,SAASI,EAAKL,GAASC,GAAOC,GAAK;AACxC,SAAOC,EAAaH,GAASC,IAAQ,EAAE,GAAGG,EAAK,CAAC,YAAY,KAAK,GAAGH,CAAK,EAAC,IAAK,QAAWA,EAAM,QAAQ;AAC1G;AAEA,SAASG,EAAKE,GAAMC,GAAQ;AAC1B,QAAMC,IAAS,CAAE;AACjB,aAAWN,KAAOK;AAChB,IAAKD,EAAK,SAASJ,CAAG,MACpBM,EAAON,CAAG,IAAIK,EAAOL,CAAG;AAG5B,SAAOM;AACT;"}
1
+ {"version":3,"file":"jsx-runtime.js","sources":["../src/jsx-runtime.js"],"sourcesContent":["import { createMarkup } from \"./markup.ts\";\nexport { Passthrough as Fragment } from \"./views/passthrough.ts\";\n\n/**\n * JSX function for elements with dynamic children.\n */\nexport function jsx(element, props, key) {\n return createMarkup(element, props ? { ...omit([\"children\", \"key\"], props) } : undefined, ...[props.children]);\n}\n\n/**\n * JSX function for elements with static children.\n */\nexport function jsxs(element, props, key) {\n return createMarkup(element, props ? { ...omit([\"children\", \"key\"], props) } : undefined, props.children);\n}\n\nfunction omit(keys, object) {\n const result = {};\n for (const key in object) {\n if (!keys.includes(key)) {\n result[key] = object[key];\n }\n }\n return result;\n}\n"],"names":["jsx","element","props","key","createMarkup","omit","jsxs","keys","object","result"],"mappings":";;AAMO,SAASA,EAAIC,GAASC,GAAOC,GAAK;AACvC,SAAOC,EAAaH,GAASC,IAAQ,EAAE,GAAGG,EAAK,CAAC,YAAY,KAAK,GAAGH,CAAK,EAAC,IAAK,QAAeA,EAAM,QAAS;AAC/G;AAKO,SAASI,EAAKL,GAASC,GAAOC,GAAK;AACxC,SAAOC,EAAaH,GAASC,IAAQ,EAAE,GAAGG,EAAK,CAAC,YAAY,KAAK,GAAGH,CAAK,EAAC,IAAK,QAAWA,EAAM,QAAQ;AAC1G;AAEA,SAASG,EAAKE,GAAMC,GAAQ;AAC1B,QAAMC,IAAS,CAAE;AACjB,aAAWN,KAAOK;AAChB,IAAKD,EAAK,SAASJ,CAAG,MACpBM,EAAON,CAAG,IAAIK,EAAOL,CAAG;AAG5B,SAAOM;AACT;"}
package/dist/markup.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Dolla } from "./modules/dolla.js";
2
- import { MaybeSignal, type Signal } from "./signals.js";
2
+ import { MaybeState, type State } from "./state.js";
3
3
  import type { Renderable, Stringable } from "./types.js";
4
4
  import { type ViewFunction, type ViewContext, type ViewResult } from "./view.js";
5
5
  export interface ElementContext {
@@ -7,13 +7,21 @@ export interface ElementContext {
7
7
  * The root Dolla instance this element belongs to.
8
8
  */
9
9
  root: Dolla;
10
+ /**
11
+ * Storage for context variables.
12
+ */
13
+ data: Record<string | symbol, unknown>;
14
+ /**
15
+ * A reference to the parent context.
16
+ */
17
+ parent?: ElementContext;
10
18
  /**
11
19
  * Whether to create DOM nodes in the SVG namespace. An `<svg>` element will set this to true and pass it down to children.
12
20
  */
13
21
  isSVG?: boolean;
14
22
  }
15
23
  /**
16
- * Markup is a set of element metadata that hasn't been rendered to a DOMHandle yet.
24
+ * Markup is a set of element metadata that hasn't been constructed into a MarkupNode yet.
17
25
  */
18
26
  export interface Markup {
19
27
  type: string | ViewFunction<any>;
@@ -21,38 +29,37 @@ export interface Markup {
21
29
  children?: Markup[];
22
30
  }
23
31
  /**
24
- * DOMHandle is the generic interface for an element that can be manipulated by the framework.
32
+ * A DOM node that has been constructed from a Markup object.
25
33
  */
26
- export interface DOMHandle {
34
+ export interface MarkupNode {
27
35
  readonly node?: Node;
28
- readonly connected: boolean;
29
- connect(parent: Node, after?: Node): void;
30
- disconnect(): void;
31
- setChildren(children: DOMHandle[]): void;
36
+ readonly isMounted: boolean;
37
+ mount(parent: Node, after?: Node): void;
38
+ unmount(): void;
32
39
  }
33
40
  export declare function isMarkup(value: unknown): value is Markup;
34
- export declare function isDOMHandle(value: unknown): value is DOMHandle;
41
+ export declare function isNode(value: unknown): value is MarkupNode;
35
42
  export declare function toMarkup(renderables: Renderable | Renderable[]): Markup[];
36
43
  export interface MarkupAttributes {
37
44
  $text: {
38
- value: MaybeSignal<Stringable>;
45
+ value: MaybeState<Stringable>;
39
46
  };
40
47
  $cond: {
41
- $predicate: Signal<any>;
48
+ $predicate: State<any>;
42
49
  thenContent?: Renderable;
43
50
  elseContent?: Renderable;
44
51
  };
45
52
  $repeat: {
46
- $items: Signal<any[]>;
53
+ $items: State<any[]>;
47
54
  keyFn: (value: any, index: number) => string | number | symbol;
48
- renderFn: ($item: Signal<any>, $index: Signal<number>, c: ViewContext) => ViewResult;
55
+ renderFn: ($item: State<any>, $index: State<number>, c: ViewContext) => ViewResult;
49
56
  };
50
57
  $observer: {
51
- signals: Signal<any>[];
58
+ states: State<any>[];
52
59
  renderFn: (...items: any) => Renderable;
53
60
  };
54
61
  $outlet: {
55
- $children: Signal<DOMHandle[]>;
62
+ $children: State<MarkupNode[]>;
56
63
  };
57
64
  $node: {
58
65
  value: Node;
@@ -65,30 +72,37 @@ export interface MarkupAttributes {
65
72
  }
66
73
  export declare function createMarkup<T extends keyof MarkupAttributes>(type: T, attributes: MarkupAttributes[T], ...children: Renderable[]): Markup;
67
74
  export declare function createMarkup<I>(type: ViewFunction<I>, attributes?: I, ...children: Renderable[]): Markup;
75
+ /**
76
+ * Generate markup with HTML in a tagged template literal.
77
+ */
78
+ export declare const html: (strings: TemplateStringsArray, ...values: any[]) => Markup | Markup[];
68
79
  /**
69
80
  * Displays content conditionally. When `predicate` holds a truthy value, `thenContent` is displayed; when `predicate` holds a falsy value, `elseContent` is displayed.
70
81
  */
71
- export declare function cond(predicate: MaybeSignal<any>, thenContent?: Renderable, elseContent?: Renderable): Markup;
82
+ export declare function cond(predicate: MaybeState<any>, thenContent?: Renderable, elseContent?: Renderable): Markup;
72
83
  /**
73
84
  * Calls `renderFn` for each item in `items`. Dynamically adds and removes views as items change.
74
85
  * The result of `keyFn` is used to compare items and decide if item was added, removed or updated.
75
86
  */
76
- export declare function repeat<T>(items: MaybeSignal<T[]>, keyFn: (value: T, index: number) => string | number | symbol, renderFn: ($value: Signal<T>, $index: Signal<number>, ctx: ViewContext) => ViewResult): Markup;
87
+ export declare function repeat<T>(items: MaybeState<T[]>, keyFn: (value: T, index: number) => string | number | symbol, renderFn: ($value: State<T>, $index: State<number>, ctx: ViewContext) => ViewResult): Markup;
77
88
  /**
78
89
  * Render `content` into a `parent` node anywhere in the page, rather than at its position in the view.
79
90
  */
80
- export declare function portal(content: Renderable, parent: Node): Markup;
91
+ export declare function portal(parent: Node, content: Renderable): Markup;
81
92
  /**
82
- * A special kind of signal exclusively for storing references to DOM nodes.
93
+ * A special kind of State exclusively for storing references to DOM nodes.
83
94
  */
84
95
  export declare function createRef<T extends Node>(): Ref<T>;
85
96
  export declare function isRef<T extends Node>(value: any): value is Ref<T>;
86
- export interface Ref<T extends Node> extends Signal<T | undefined> {
97
+ export interface Ref<T extends Node> extends State<T | undefined> {
87
98
  node: T | undefined;
88
99
  }
89
- export declare function renderMarkupToDOM(markup: Markup | Markup[], elementContext: ElementContext): DOMHandle[];
90
100
  /**
91
- * Combines one or more DOMHandles into a single DOMHandle.
101
+ * Construct Markup metadata into a set of MarkupNodes.
102
+ */
103
+ export declare function constructMarkup(elementContext: ElementContext, markup: Markup | Markup[]): MarkupNode[];
104
+ /**
105
+ * Combines one or more MarkupNodes into a single MarkupNode.
92
106
  */
93
- export declare function getRenderHandle(handles: DOMHandle[]): DOMHandle;
107
+ export declare function mergeNodes(nodes: MarkupNode[]): MarkupNode;
94
108
  export declare function isRenderable(value: unknown): value is Renderable;
@@ -1,8 +1,9 @@
1
- import { createRef, isRef, type DOMHandle, type Markup } from "../markup.js";
2
- import { createSettableSignal, createSignal, derive, designalify, signalify, toSettableSignal, watch, type Signal } from "../signals.js";
3
- import { type ViewFunction } from "../view.js";
1
+ import { createRef, isRef, MarkupNode, type Markup } from "../markup.js";
2
+ import { createSettableState, createState, derive, toSettableState, toState, valueOf, watch, type State } from "../state.js";
3
+ import { type ViewFunction, type ViewNode } from "../view.js";
4
+ import { type CrashViewProps } from "../views/default-crash-view.js";
4
5
  import { HTTP } from "./http.js";
5
- import { Language } from "./language.js";
6
+ import { I18n } from "./i18n.js";
6
7
  import { Render } from "./render.js";
7
8
  import { Router } from "./router.js";
8
9
  export type Environment = "development" | "production";
@@ -39,23 +40,39 @@ export type LoggerOptions = {
39
40
  };
40
41
  export declare class Dolla {
41
42
  #private;
42
- http: HTTP;
43
- language: Language;
44
- render: Render;
45
- router: Router;
43
+ readonly http: HTTP;
44
+ readonly i18n: I18n;
45
+ readonly render: Render;
46
+ readonly router: Router;
46
47
  constructor();
47
- createSignal: typeof createSignal;
48
- createSettableSignal: typeof createSettableSignal;
49
- toSettableSignal: typeof toSettableSignal;
50
- signalify: typeof signalify;
51
- designalify: typeof designalify;
48
+ createState: typeof createState;
49
+ createSettableState: typeof createSettableState;
50
+ toSettableState: typeof toSettableState;
51
+ toState: typeof toState;
52
+ valueOf: typeof valueOf;
52
53
  derive: typeof derive;
53
54
  watch: typeof watch;
54
55
  createRef: typeof createRef;
55
56
  isRef: typeof isRef;
57
+ /**
58
+ * True when the app is connected to a DOM node and displayed to the user.
59
+ */
56
60
  get isMounted(): boolean;
57
- get env(): Environment;
58
- set env(value: Environment);
61
+ /**
62
+ * Get the current environment that this app is running in.
63
+ * Environment affects which log messages will print and how much debugging info is included in the DOM.
64
+ */
65
+ getEnv(): Environment;
66
+ /**
67
+ * Sets the environment that this app is running in.
68
+ * Environment affects which log messages will print and how much debugging info is included in the DOM.
69
+ */
70
+ setEnv(value: Environment): void;
71
+ /**
72
+ * Sets the view that will be shown when the `crash` method is called on any logger.
73
+ * When a crash is reported the app will be unmounted and replaced with this crash page.
74
+ */
75
+ setCrashView(view: ViewFunction<CrashViewProps>): void;
59
76
  mount(selector: string, view?: ViewFunction<any>): Promise<void>;
60
77
  mount(element: HTMLElement, view?: ViewFunction<any>): Promise<void>;
61
78
  unmount(): Promise<void>;
@@ -82,6 +99,13 @@ export declare class Dolla {
82
99
  */
83
100
  setLoggles(options: Partial<Loggles>): void;
84
101
  setLogFilter(filter: string | RegExp): void;
85
- createLogger(name: string | Signal<string>, options?: LoggerOptions): Logger;
86
- constructView<P>(view: ViewFunction<P>, props: P, children?: Markup[]): DOMHandle;
102
+ createLogger(name: string | State<string>, options?: LoggerOptions): Logger;
103
+ /**
104
+ *
105
+ */
106
+ constructView<P>(view: ViewFunction<P>, props: P, children?: Markup[]): ViewNode;
107
+ /**
108
+ *
109
+ */
110
+ constructMarkup(markup: Markup | Markup[]): MarkupNode;
87
111
  }
@@ -0,0 +1,93 @@
1
+ import { MaybeState, type State } from "../state.js";
2
+ import type { Dolla } from "./dolla.js";
3
+ /**
4
+ * An object where values are either a translated string or another nested Translation object.
5
+ */
6
+ type LocalizedStrings = Record<string, string | Record<string, string | Record<string, string | Record<string, string>>>>;
7
+ export interface TranslationConfig {
8
+ /**
9
+ * Name of the locale this translation is for (BCP 47 locale names recommended).
10
+ */
11
+ locale: string;
12
+ /**
13
+ * Path to a JSON file with translated strings for this language.
14
+ */
15
+ path?: string;
16
+ /**
17
+ * A callback function that returns a Promise that resolves to the translation object for this language.
18
+ */
19
+ fetch?: () => Promise<LocalizedStrings>;
20
+ }
21
+ export type I18nSetupOptions = {
22
+ /**
23
+ * Default locale to load on startup
24
+ */
25
+ locale?: string | null;
26
+ translations: TranslationConfig[];
27
+ };
28
+ export type TOptions = {
29
+ /**
30
+ *
31
+ */
32
+ count?: MaybeState<number>;
33
+ /**
34
+ *
35
+ */
36
+ context?: MaybeState<string>;
37
+ [value: string]: MaybeState<any>;
38
+ };
39
+ /**
40
+ * Dolla's I(nternationalizatio)n module. Manages language translations and locale-based formatting.
41
+ */
42
+ export declare class I18n {
43
+ #private;
44
+ $locale: State<string | undefined>;
45
+ constructor(dolla: Dolla);
46
+ get locales(): string[];
47
+ setup(options: I18nSetupOptions): void;
48
+ setLocale(name: string): Promise<void>;
49
+ /**
50
+ * Returns a State containing the value at `key`.
51
+
52
+ * @param key - Key to the translated value.
53
+ * @param options - A map of {{placeholder}} names and the values to replace them with.
54
+ *
55
+ * @example
56
+ * const $value = t("your.key.here");
57
+ */
58
+ t(key: string, options?: TOptions): State<string>;
59
+ /**
60
+ * Creates an `Intl.Collator` configured for the current locale.
61
+ * NOTE: The Collator remains bound to the locale it was created with, even when the app's locale changes.
62
+ *
63
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#options
64
+ */
65
+ collator(options?: Intl.CollatorOptions): Intl.Collator;
66
+ /**
67
+ * Returns a State containing the number formatted for the current locale. Uses `Intl.NumberFormat` under the hood.
68
+ *
69
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
70
+ */
71
+ number(count: MaybeState<number | bigint>, options?: Intl.NumberFormatOptions): State<string>;
72
+ /**
73
+ * Returns a State containing the date formatted for the current locale. Uses `Intl.DateTimeFormat` under the hood.
74
+ *
75
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
76
+ *
77
+ * @example
78
+ * const date = new Date();
79
+ * const $formatted = Dolla.i18n.dateTime(date, { dateFormat: "short" });
80
+ */
81
+ dateTime(date?: MaybeState<string | number | Date | undefined>, options?: Intl.DateTimeFormatOptions): State<string>;
82
+ /**
83
+ * Returns a State containing the date formatted for the current locale. Uses `Intl.DateTimeFormat` under the hood.
84
+ *
85
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options
86
+ *
87
+ * @example
88
+ * const list = new Date();
89
+ * const $formatted = Dolla.i18n.list(list, { });
90
+ */
91
+ list(list: MaybeState<Iterable<string>>, options?: Intl.ListFormatOptions): State<string>;
92
+ }
93
+ export {};
@@ -1,6 +1,5 @@
1
- import { type DOMHandle, type Markup } from "../markup.js";
2
1
  import { type Stringable } from "../types.js";
3
- import { type ViewFunction } from "../view.js";
2
+ import { ViewNode, type ViewFunction } from "../view.js";
4
3
  import type { Dolla } from "./dolla.js";
5
4
  export interface RouteMatchContext {
6
5
  /**
@@ -41,7 +40,7 @@ export interface RouteConfig {
41
40
  }
42
41
  export interface RouteLayer {
43
42
  id: number;
44
- markup: Markup;
43
+ view: ViewFunction<{}>;
45
44
  }
46
45
  /**
47
46
  * Object passed to redirect callbacks. Contains information useful for determining how to redirect.
@@ -101,34 +100,34 @@ export interface RouterSetupOptions {
101
100
  }
102
101
  export interface RouterElements {
103
102
  readonly rootElement?: HTMLElement;
104
- readonly rootView?: DOMHandle;
103
+ readonly rootView?: ViewNode;
105
104
  }
106
105
  export declare class Router {
107
106
  #private;
108
107
  /**
109
108
  * The currently matched route pattern, if any.
110
109
  */
111
- $pattern: import("../signals.js").Signal<string | null>;
110
+ $pattern: import("../state.js").State<string | null>;
112
111
  /**
113
112
  * The current URL path.
114
113
  */
115
- $path: import("../signals.js").Signal<string>;
114
+ $path: import("../state.js").State<string>;
116
115
  /**
117
116
  * The current named path params.
118
117
  */
119
- $params: import("../signals.js").Signal<ParsedParams>;
118
+ $params: import("../state.js").State<ParsedParams>;
120
119
  /**
121
120
  * The current query params. Changes to this object will be reflected in the URL.
122
121
  */
123
- $query: import("../signals.js").Signal<ParsedQuery>;
122
+ $query: import("../state.js").State<ParsedQuery>;
124
123
  constructor(dolla: Dolla, elements: RouterElements);
125
124
  setup(options: RouterSetupOptions): void;
126
125
  /**
127
126
  * Navigates to another route.
128
127
  *
129
128
  * @example
130
- * navigate("/login"); // navigate to `/login`
131
- * navigate(["/users", 215], { replace: true }); // replace current history entry with `/users/215`
129
+ * Dolla.router.go("/login"); // navigate to `/login`
130
+ * Dolla.router.go["/users", 215], { replace: true }); // replace current history entry with `/users/215`
132
131
  */
133
132
  go(path: Stringable | Stringable[], options?: NavigateOptions): void;
134
133
  /**
@@ -1,27 +1,26 @@
1
- import { type DOMHandle, type ElementContext, type Markup } from "../markup.js";
2
- import { type Signal, type StopFunction } from "../signals.js";
1
+ import { type MarkupNode, type ElementContext, type Markup } from "../markup.js";
2
+ import { type State, type StopFunction } from "../state.js";
3
3
  import { type Renderable } from "../types.js";
4
4
  export interface ConditionalConfig {
5
- $predicate: Signal<any>;
5
+ $predicate: State<any>;
6
6
  thenContent?: Renderable;
7
7
  elseContent?: Renderable;
8
8
  elementContext: ElementContext;
9
9
  }
10
- export declare class Conditional implements DOMHandle {
10
+ export declare class Conditional implements MarkupNode {
11
11
  node: Node;
12
12
  endNode: Node;
13
- $predicate: Signal<any>;
13
+ $predicate: State<any>;
14
14
  stopCallback?: StopFunction;
15
15
  thenContent?: Markup[];
16
16
  elseContent?: Markup[];
17
- connectedContent: DOMHandle[];
17
+ connectedContent: MarkupNode[];
18
18
  elementContext: ElementContext;
19
19
  initialUpdateHappened: boolean;
20
20
  previousValue?: any;
21
21
  constructor(config: ConditionalConfig);
22
- get connected(): boolean;
23
- connect(parent: Node, after?: Node | undefined): void;
24
- disconnect(): void;
22
+ get isMounted(): boolean;
23
+ mount(parent: Node, after?: Node | undefined): void;
24
+ unmount(): void;
25
25
  update(value: any): void;
26
- setChildren(children: DOMHandle[]): Promise<void>;
27
26
  }
@@ -1,27 +1,31 @@
1
- import { type DOMHandle, type ElementContext, type Markup } from "../markup.js";
2
- import { type StopFunction } from "../signals.js";
1
+ import { type ElementContext, type Markup, type MarkupNode, type Ref } from "../markup.js";
2
+ import { type StopFunction } from "../state.js";
3
3
  type HTMLOptions = {
4
4
  elementContext: ElementContext;
5
5
  tag: string;
6
- props?: any;
6
+ props: Record<string, any>;
7
7
  children?: Markup[];
8
8
  };
9
- export declare class HTML implements DOMHandle {
9
+ export declare class HTML implements MarkupNode {
10
10
  node: HTMLElement | SVGElement;
11
11
  props: Record<string, any>;
12
- children: DOMHandle[];
12
+ children: MarkupNode[];
13
13
  stopCallbacks: StopFunction[];
14
14
  elementContext: ElementContext;
15
15
  uniqueId: string;
16
+ ref?: Ref<any>;
16
17
  canClickAway: boolean;
17
- get connected(): boolean;
18
+ get isMounted(): boolean;
18
19
  constructor({ tag, props, children, elementContext }: HTMLOptions);
19
- connect(parent: Node, after?: Node): void;
20
- disconnect(): void;
21
- setChildren(next: DOMHandle[]): void;
20
+ mount(parent: Node, after?: Node): void;
21
+ unmount(): void;
22
22
  getUpdateKey(type: string, value: string | number): string;
23
23
  applyProps(element: HTMLElement | SVGElement, props: Record<string, unknown>): void;
24
- applyStyles(element: HTMLElement | SVGElement, styles: string | Record<string, any>, stopCallbacks: StopFunction[]): () => void;
24
+ applyStyles(element: HTMLElement | SVGElement, styles: unknown, stopCallbacks: StopFunction[]): () => void;
25
25
  applyClasses(element: HTMLElement | SVGElement, classes: unknown, stopCallbacks: StopFunction[]): () => void;
26
26
  }
27
+ /**
28
+ * Converts a camelCase string to kebab-case.
29
+ */
30
+ export declare function camelToKebab(value: string): string;
27
31
  export {};
@@ -1,29 +1,28 @@
1
- import { type DOMHandle, type ElementContext } from "../markup.js";
2
- import { type Signal } from "../signals.js";
1
+ import { type ElementContext, type MarkupNode } from "../markup.js";
2
+ import { type State } from "../state.js";
3
3
  import type { Renderable } from "../types.js";
4
4
  interface ObserverOptions {
5
5
  elementContext: ElementContext;
6
- signals: Signal<any>[];
6
+ states: State<any>[];
7
7
  renderFn: (...values: any) => Renderable;
8
8
  }
9
9
  /**
10
10
  * Displays dynamic children without a parent element.
11
11
  */
12
- export declare class Observer implements DOMHandle {
12
+ export declare class Observer implements MarkupNode {
13
13
  node: Node;
14
14
  endNode: Node;
15
- connectedViews: DOMHandle[];
15
+ connectedViews: MarkupNode[];
16
16
  renderFn: (...values: any) => Renderable;
17
17
  elementContext: ElementContext;
18
18
  observerControls: {
19
19
  start: () => void;
20
20
  stop: () => void;
21
21
  };
22
- get connected(): boolean;
23
- constructor({ signals, renderFn, elementContext }: ObserverOptions);
24
- connect(parent: Node, after?: Node): void;
25
- disconnect(): void;
26
- setChildren(): Promise<void>;
22
+ get isMounted(): boolean;
23
+ constructor({ states, renderFn, elementContext }: ObserverOptions);
24
+ mount(parent: Node, after?: Node): void;
25
+ unmount(): void;
27
26
  cleanup(): void;
28
27
  update(...children: Renderable[]): void;
29
28
  }
@@ -1,23 +1,22 @@
1
- import { type DOMHandle, type ElementContext } from "../markup.js";
2
- import { type Signal, type StopFunction } from "../signals.js";
1
+ import { type MarkupNode, type ElementContext } from "../markup.js";
2
+ import { type State, type StopFunction } from "../state.js";
3
3
  export interface OutletConfig {
4
- $children: Signal<DOMHandle[]>;
4
+ $children: State<MarkupNode[]>;
5
5
  elementContext: ElementContext;
6
6
  }
7
7
  /**
8
8
  * Manages an array of DOMHandles.
9
9
  */
10
- export declare class Outlet implements DOMHandle {
10
+ export declare class Outlet implements MarkupNode {
11
11
  node: Node;
12
12
  endNode: Node;
13
- $children: Signal<DOMHandle[]>;
13
+ $children: State<MarkupNode[]>;
14
14
  stopCallback?: StopFunction;
15
- connectedChildren: DOMHandle[];
15
+ connectedChildren: MarkupNode[];
16
16
  elementContext: ElementContext;
17
17
  constructor(config: OutletConfig);
18
- get connected(): boolean;
19
- connect(parent: Node, after?: Node | undefined): void;
20
- disconnect(): void;
21
- update(newChildren: DOMHandle[]): void;
22
- setChildren(children: DOMHandle[]): void;
18
+ get isMounted(): boolean;
19
+ mount(parent: Node, after?: Node | undefined): void;
20
+ unmount(): void;
21
+ update(newChildren: MarkupNode[]): void;
23
22
  }
@@ -1,4 +1,4 @@
1
- import { type DOMHandle, type ElementContext } from "../markup.js";
1
+ import { type MarkupNode, type ElementContext } from "../markup.js";
2
2
  import { type Renderable } from "../types.js";
3
3
  interface PortalConfig {
4
4
  content: Renderable;
@@ -8,13 +8,12 @@ interface PortalConfig {
8
8
  /**
9
9
  * Renders content into a specified parent node.
10
10
  */
11
- export declare class Portal implements DOMHandle {
11
+ export declare class Portal implements MarkupNode {
12
12
  config: PortalConfig;
13
- handle?: DOMHandle;
14
- get connected(): boolean;
13
+ handle?: MarkupNode;
14
+ get isMounted(): boolean;
15
15
  constructor(config: PortalConfig);
16
- connect(_parent: Node, _after?: Node): void;
17
- disconnect(): void;
18
- setChildren(children: DOMHandle[]): void;
16
+ mount(_parent: Node, _after?: Node): void;
17
+ unmount(): void;
19
18
  }
20
19
  export {};
@@ -1,34 +1,33 @@
1
- import { type DOMHandle, type ElementContext } from "../markup.js";
2
- import { type Signal, type SignalSetter, type StopFunction } from "../signals.js";
1
+ import { type MarkupNode, type ElementContext } from "../markup.js";
2
+ import { type State, type Setter, type StopFunction } from "../state.js";
3
3
  import { type ViewContext, type ViewResult } from "../view.js";
4
4
  interface RepeatOptions<T> {
5
5
  elementContext: ElementContext;
6
- $items: Signal<T[]>;
6
+ $items: State<T[]>;
7
7
  keyFn: (value: T, index: number) => string | number | symbol;
8
- renderFn: ($value: Signal<T>, $index: Signal<number>, ctx: ViewContext) => ViewResult;
8
+ renderFn: ($value: State<T>, $index: State<number>, ctx: ViewContext) => ViewResult;
9
9
  }
10
10
  type ConnectedItem<T> = {
11
11
  key: any;
12
- $value: Signal<T>;
13
- setValue: SignalSetter<T>;
14
- $index: Signal<number>;
15
- setIndex: SignalSetter<number>;
16
- handle: DOMHandle;
12
+ $value: State<T>;
13
+ setValue: Setter<T>;
14
+ $index: State<number>;
15
+ setIndex: Setter<number>;
16
+ handle: MarkupNode;
17
17
  };
18
- export declare class Repeat<T> implements DOMHandle {
18
+ export declare class Repeat<T> implements MarkupNode {
19
19
  node: Node;
20
20
  endNode: Node;
21
- $items: Signal<T[]>;
21
+ $items: State<T[]>;
22
22
  stopCallback?: StopFunction;
23
23
  connectedItems: ConnectedItem<T>[];
24
24
  elementContext: ElementContext;
25
- renderFn: ($value: Signal<T>, $index: Signal<number>, ctx: ViewContext) => ViewResult;
25
+ renderFn: ($value: State<T>, $index: State<number>, ctx: ViewContext) => ViewResult;
26
26
  keyFn: (value: T, index: number) => string | number | symbol;
27
- get connected(): boolean;
27
+ get isMounted(): boolean;
28
28
  constructor({ elementContext, $items, renderFn, keyFn }: RepeatOptions<T>);
29
- connect(parent: Node, after?: Node): void;
30
- disconnect(): void;
31
- setChildren(): void;
29
+ mount(parent: Node, after?: Node): void;
30
+ unmount(): void;
32
31
  _cleanup(): void;
33
32
  _update(value: T[]): void;
34
33
  }