@manyducks.co/dolla 2.0.0-alpha.3 → 2.0.0-alpha.31

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 (71) hide show
  1. package/README.md +31 -951
  2. package/dist/core/batch.d.ts +17 -0
  3. package/dist/core/context.d.ts +94 -0
  4. package/dist/core/dolla.d.ts +161 -0
  5. package/dist/core/markup.d.ts +91 -0
  6. package/dist/core/nodes/dom.d.ts +13 -0
  7. package/dist/core/nodes/html.d.ts +39 -0
  8. package/dist/core/nodes/observer.d.ts +30 -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/repeat.d.ts +36 -0
  12. package/dist/core/nodes/view.d.ts +92 -0
  13. package/dist/core/ref.d.ts +29 -0
  14. package/dist/core/state.d.ts +126 -0
  15. package/dist/core/stats.d.ts +31 -0
  16. package/dist/core/store.d.ts +62 -0
  17. package/dist/core/symbols.d.ts +7 -0
  18. package/dist/index.d.ts +18 -11
  19. package/dist/index.js +1157 -1159
  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-D1i09ddt.js +1563 -0
  28. package/dist/markup-D1i09ddt.js.map +1 -0
  29. package/dist/modules/http.d.ts +5 -5
  30. package/dist/modules/i18n.d.ts +129 -0
  31. package/dist/modules/router.d.ts +37 -48
  32. package/dist/typeChecking.d.ts +2 -2
  33. package/dist/types.d.ts +12 -13
  34. package/dist/utils.d.ts +14 -2
  35. package/dist/views/default-crash-view.d.ts +1 -1
  36. package/dist/views/passthrough.d.ts +2 -2
  37. package/docs/http.md +29 -0
  38. package/docs/i18n.md +38 -0
  39. package/docs/index.md +10 -0
  40. package/docs/router.md +77 -0
  41. package/docs/setup.md +31 -0
  42. package/docs/state.md +141 -0
  43. package/docs/stores.md +62 -0
  44. package/docs/views.md +308 -0
  45. package/index.d.ts +2 -2
  46. package/notes/TODO.md +6 -0
  47. package/notes/context-vars.md +21 -0
  48. package/notes/readme-scratch.md +222 -0
  49. package/notes/route-middleware.md +42 -0
  50. package/notes/scratch.md +195 -7
  51. package/notes/stores.md +73 -0
  52. package/package.json +12 -14
  53. package/tests/{signals.test.js → state.test.js} +6 -6
  54. package/vite.config.js +0 -10
  55. package/dist/markup.d.ts +0 -100
  56. package/dist/modules/dolla.d.ts +0 -111
  57. package/dist/modules/language.d.ts +0 -41
  58. package/dist/modules/render.d.ts +0 -17
  59. package/dist/nodes/cond.d.ts +0 -26
  60. package/dist/nodes/html.d.ts +0 -26
  61. package/dist/nodes/observer.d.ts +0 -29
  62. package/dist/nodes/outlet.d.ts +0 -22
  63. package/dist/nodes/portal.d.ts +0 -19
  64. package/dist/nodes/repeat.d.ts +0 -34
  65. package/dist/nodes/text.d.ts +0 -19
  66. package/dist/passthrough-DrtCifRF.js +0 -1228
  67. package/dist/passthrough-DrtCifRF.js.map +0 -1
  68. package/dist/signals.d.ts +0 -101
  69. package/dist/view.d.ts +0 -50
  70. /package/dist/{routing.d.ts → modules/router.utils.d.ts} +0 -0
  71. /package/dist/{routing.test.d.ts → modules/router.utils.test.d.ts} +0 -0
package/notes/scratch.md CHANGED
@@ -1,5 +1,193 @@
1
1
  # Scratch Note
2
2
 
3
+ ---
4
+
5
+ Bring the $ back and the name full circle.
6
+
7
+ ```js
8
+ import { $, $$ } from "@manyducks.co/dolla";
9
+
10
+ // Shorthand dolla sign
11
+
12
+ // An initial value (with optional options object) creates a state.
13
+ const [$count, setCount] = $(0);
14
+ // = createState(0)
15
+
16
+ // An array and a function derives a state.
17
+ const $doubled = $.map([$count], (count) => count * 2);
18
+ // = derive([$count], (count) => count * 2);
19
+
20
+ // A state returns the same state.
21
+ const $sameCount = $.from($count);
22
+ const $wrapped = $.from({ message: "This is a state with no setter." });
23
+ // = toState($count)
24
+
25
+ // Get value from a state. Values that are not states are returned directly.
26
+ const count = $.get($count);
27
+ ```
28
+
29
+ What about other operators like RxJS?
30
+
31
+ ```js
32
+ // These would be functionally equivalent.
33
+ const $doubled = $count.pipe($.map((count) => count * 2));
34
+ const $doubled = $.map([$count], (count) => count * 2);
35
+
36
+ // Chainable. Get doubled value, but only update if it's between 10 and 100.
37
+ const $boundedDouble = $count.pipe(
38
+ // Transforms the value
39
+ $.map((count) => count * 2),
40
+
41
+ // Receives the value when it changes without affecting the output.
42
+ // Only receives values while this state is actively being watched.
43
+ $.tap((count) => console.log(`doubled value is ${count}`))
44
+
45
+ // Value only changes if it's within the range.
46
+ $.filter((count) => count >= 10 && count <= 100),
47
+ );
48
+
49
+ // Could have a top level pipe operator
50
+ const $boundedDouble = $.pipe(
51
+ [$count],
52
+ $.map((count) => count * 2),
53
+ $.tap((count) => console.log(`doubled value is ${count}`))
54
+ $.filter((count) => count >= 10 && count <= 100),
55
+ );
56
+
57
+ // Could also be chainable
58
+ const $boundedDouble = $count
59
+ .map((count) => count * 2)
60
+ .tap((count) => console.log(`doubled value is ${count}`))
61
+ .filter((count) => count >= 10 && count <= 100);
62
+
63
+ // I kind of like this more than the current derive. It's cleaner.
64
+ $count.map(c => c * 2);
65
+ $count.merge([$other], (c, o) => c * o);
66
+
67
+ // Another way to merge multiple.
68
+ $.merge([$count, $other], (c, o) => c * o);
69
+
70
+ // What if you want to add something in the middle?
71
+
72
+ const $example = $count
73
+ .map((count) => count * 2)
74
+ .tap((count) => console.log(`doubled value is ${count}`))
75
+ .merge([$other1, $other2], (count, other1, other2) => /* ... */)
76
+ .filter((value) => value >= 10 && value <= 100);
77
+
78
+ // Is this a good pattern?
79
+ $count
80
+ .merge([$other], (count, other) => count * other)
81
+ .merge([$another], (merged, another) => merged * another);
82
+ // I think it gets a little weird to follow.
83
+
84
+ // equivalent to
85
+ derive(
86
+ [
87
+ derive([$count, $other], (count, other) => count * other),
88
+ $another
89
+ ],
90
+ (merged, another) => merged * another)
91
+ // Is this a pattern? Yeah, I guess I do that. Just never in line like that.
92
+
93
+ // Do we want to handle errors?
94
+ // I feel like errors usually happen in watchers though.
95
+ $boundedDouble.watch((value) => {
96
+ // Received a value.
97
+ }, (error) => {
98
+ // Something threw an error.
99
+ });
100
+ // Or like this.
101
+ $boundedDouble.watch({
102
+ change: (value) => {
103
+ // Received a value.
104
+ // This code is most likely to throw an error.
105
+ // Should errors here be passed to the error callback?
106
+ // What is the point if you can just try/catch?
107
+
108
+ // Although if you don't then Dolla could use this to catch
109
+ // and trace errors better than it does now.
110
+ },
111
+ error: (error) => {
112
+ // Something threw an error.
113
+ }
114
+ });
115
+
116
+ // Filter derives a new state where the value only updates if the function returns truthy.
117
+ const $evens = $count.pipe($.filter((count) => count % 1 === 0));
118
+ // This is equivalent to
119
+ const $events = $.map([$count], (count) => count, { equals: (a, b) => a % 1 === 0 });
120
+
121
+ function filter(...args) {
122
+ if (isArray(args[0]) && isFunction(args[1])) {
123
+ // Standalone signature. Returns a new derived state.
124
+ } else if (args.length === 1 && isFunction(args[1])) {
125
+ // Curried signature. Returns a function that takes an array of states
126
+ // and returns one with args[1] as the equality check.
127
+ }
128
+ }
129
+ ```
130
+
131
+ And you can write your own operators that implement these two signatures.
132
+
133
+ ```js
134
+ // Here's one I might want to include.
135
+ // Use this to prevent ever getting a null value.
136
+ compare((next, previous) => next ?? previous ?? "default");
137
+
138
+ function compare(...args) {}
139
+ ```
140
+
141
+ ---
142
+
143
+ I've been looking into other libraries that don't make you track your dependencies specifically. I think this is weird and unhinged to be honest. Calling functions with side effects that magically re-run things when the value changes is a truly weird and unexpected lifecycle. At least if you're explicitly tracking dependencies you know exactly what depends on what at a glance. Getting the computer to figure it out for you doesn't seem smart.
144
+
145
+ ```js
146
+ import { $ } from "@manyducks.co/dolla";
147
+
148
+ const [count, setCount] = $(0);
149
+
150
+ const doubled = $.computed(() => count() * 2);
151
+
152
+ $.effect(() => {
153
+ console.log(doubled());
154
+ });
155
+
156
+ $.batch(() => {
157
+ // Set multiple things but defer updates to after this function returns.
158
+ });
159
+
160
+ // Helpers on $; can plug into template as is.
161
+ $.if(
162
+ $.computed(() => count() > 5),
163
+ <span>Greater than 5!</span>,
164
+ <span>Not greater than 5...</span>,
165
+ );
166
+
167
+ const switched = $.switch(count, [[1, "one"], [2, "two"], [3, "three"]], "more...");
168
+
169
+ $.repeat()
170
+
171
+ // TODO: How feasible is this?
172
+ <Repeat each={}>
173
+ {(item, index) => {
174
+
175
+ }}
176
+ </Repeat>
177
+
178
+ <Show when={condition}>
179
+ Condition is true.
180
+ </Show>
181
+
182
+ // Get
183
+ count();
184
+
185
+ // Set
186
+ count(52);
187
+ ```
188
+
189
+ ---
190
+
3
191
  What if Dolla was just a global object that you don't instantiate. I have never personally run into a use case for having more than one app on a page at once. In all my projects, the page and the app are synonymous.
4
192
 
5
193
  Doing this would make it possible to access things inside the Dolla app from _outside_ code such as Quill blots. Effectively all code that has access to your Dolla import is _inside_ the app.
@@ -11,8 +199,8 @@ Doing this would make it possible to access things inside the Dolla app from _ou
11
199
  import Dolla from "@manyducks.co/dolla";
12
200
 
13
201
  // Languages: add translation, set language and get localized string as a signal
14
- Dolla.language.setup({
15
- initialLanguage: Dolla.language.detect({ fallback: "ja" }), // Detect user's language and fall back to passed value
202
+ Dolla.i18n.setup({
203
+ initialLanguage: Dolla.i18n.detect({ fallback: "ja" }), // Detect user's language and fall back to passed value
16
204
  languages: [
17
205
  { name: "ja", path: "/static/locales/ja.json" },
18
206
  {
@@ -26,8 +214,8 @@ Dolla.language.setup({
26
214
  ]
27
215
  });
28
216
 
29
- Dolla.language.$current
30
- Dolla.language.t$()
217
+ Dolla.i18n.$locale
218
+ Dolla.i18n.t$()
31
219
 
32
220
  // A single setup call to keep things contained (must happen before mount)
33
221
  Dolla.router.setup({
@@ -75,10 +263,10 @@ debug.log("HELLO");
75
263
  debug.warn("THIS IS A SCOPED LOGGER");
76
264
 
77
265
  // Efficiently and safely read and mutate the DOM using Dolla's render batching
78
- Dolla.render.read(() => {
266
+ Dolla.batch.read(() => {
79
267
  // Reference DOM nodes
80
268
  });
81
- Dolla.render.update(() => {
269
+ Dolla.batch.write(() => {
82
270
  // Mutate the DOM as part of Dolla's next batch
83
271
  }, "some-key");
84
272
 
@@ -93,7 +281,7 @@ function SomeView (props: SomeViewProps, ctx: Dolla.ViewContext) {
93
281
  const debug = Dolla.createLogger("SomeView");
94
282
 
95
283
  // returns a signal and a setter function
96
- const [$someValue, setSomeValue] = Dolla.createSignal(4);
284
+ const [$someValue, setSomeValue] = Dolla.createState(4);
97
285
 
98
286
  // Router is now a part of the Dolla object
99
287
  Dolla.router.$path;
@@ -0,0 +1,73 @@
1
+ # Stores
2
+
3
+ Ideas for updating the API.
4
+
5
+ ```js
6
+ import { createStore, attachStore, useStore, createView } from "@manyducks.co/dolla";
7
+
8
+ const Counter = createStore(function (initialCount: number) {
9
+ const [$value, setValue] = createState(initialCount);
10
+
11
+ this.on("counter:increment", (e) => {
12
+ e.stopPropagation(); // Stop this event from bubbling up to counters at higher levels (if any).
13
+ setValue((current) => current + 1);
14
+ });
15
+
16
+ this.on("counter:decrement", (e) => {
17
+ e.stopPropagation();
18
+ setValue((current) => current - 1);
19
+ });
20
+
21
+ // Events can be emitted from this context in a store.
22
+ this.emit("otherEvent");
23
+
24
+ this.onMount(() => {
25
+ // Setup
26
+ // This is called based on the context the store is attached to.
27
+ // If Dolla, it's called when the app is mounted. If ViewContext, it's called when the view is mounted.
28
+ });
29
+ this.onUnmount(() => {
30
+ // Cleanup
31
+ });
32
+
33
+ // Context variables will be accessible on the same context (e.g. the view this is attached to and below)
34
+ this.get("context variable");
35
+ this.set("context variable", "context variable value");
36
+
37
+ // Stores don't have to return anything, but if they do it becomes accessible by using `useStore(ctx, Store)`.
38
+ return $value;
39
+ });
40
+
41
+ // Attach it to the app.
42
+ Dolla.attachStore(Counter(0));
43
+
44
+ const ExampleView = createView(function () {
45
+ // useStore lets you access the return value
46
+ // but the events will still be received and handled regardless
47
+ const $count = this.useStore(Counter);
48
+
49
+ // Convenience helper to attach and use in one step?
50
+ const $count = this.attachAndUseStore(Counter(0));
51
+
52
+ return html`
53
+ <button onclick=${() => this.emit("counter:decrement")}>-1</button>
54
+ <span>${$count}</span>
55
+ <button onclick=${() => this.emit("counter:increment")}>+1</button>
56
+ `;
57
+ });
58
+
59
+ // ViewContext is also still passed as a second argument if you'd rather use arrow functions to define views.
60
+ const ExampleView = createView((props, self) => {
61
+ // useStore lets you access the return value
62
+ // but the events will still be received and handled regardless
63
+ const $count = self.useStore(Counter);
64
+
65
+ return html`
66
+ <button onclick=${() => self.emit("counter:decrement")}>-1</button>
67
+ <span>${$count}</span>
68
+ <button onclick=${() => self.emit("counter:increment")}>+1</button>
69
+ `;
70
+ });
71
+ ```
72
+
73
+ This means `createStore` returns a function that is called to create a Store instance. The instance is
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@manyducks.co/dolla",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.31",
4
4
  "description": "Front-end components, routing and state management.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "sideEffects": false,
9
- "repository": "https://github.com/manyducksco/dolla",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/manyducksco/dolla.git"
12
+ },
10
13
  "scripts": {
11
14
  "test": "npm run build && node --test",
12
15
  "build:esbuild": "tsc && node build.js",
@@ -36,20 +39,15 @@
36
39
  "types": "./jsx-dev-runtime.d.ts"
37
40
  }
38
41
  },
39
- "dependencies": {
40
- "fetch-ponyfill": "^7.1.0",
41
- "history": "^5.3.0",
42
- "nanoid": "^5.0.4",
43
- "simple-color-hash": "^1.0.2",
44
- "vite": "^6.0.7"
45
- },
46
42
  "devDependencies": {
47
- "@types/node": "^18.17.6",
43
+ "@manyducks.co/emitter": "^1.1.2",
44
+ "@types/node": "^22.12.0",
48
45
  "csstype": "^3.1.3",
49
- "esbuild": "^0.24.2",
46
+ "fast-deep-equal": "^3.1.3",
50
47
  "htm": "^3.1.1",
51
- "prettier": "^3.2.4",
52
- "typescript": "^5.3.3",
53
- "zod": "^3.22.4"
48
+ "prettier": "^3.4.2",
49
+ "simple-color-hash": "^1.0.2",
50
+ "typescript": "^5.7.3",
51
+ "vite": "^6.0.11"
54
52
  }
55
53
  }
@@ -1,10 +1,10 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert";
3
3
 
4
- import { signal, derive } from "../lib/index.js";
4
+ import { createState, derive } from "../dist/index.js";
5
5
 
6
6
  test("signal", (t) => {
7
- const [$count, setCount] = signal(5);
7
+ const [$count, setCount] = createState(5);
8
8
 
9
9
  const defaultWatcher = t.mock.fn();
10
10
  const stopDefault = $count.watch(defaultWatcher);
@@ -42,8 +42,8 @@ test("signal", (t) => {
42
42
  });
43
43
 
44
44
  test("derive", (t) => {
45
- const [$one, setOne] = signal(5);
46
- const [$two, setTwo] = signal(20);
45
+ const [$one, setOne] = createState(5);
46
+ const [$two, setTwo] = createState(20);
47
47
 
48
48
  const deriveSum = t.mock.fn((one, two) => one + two);
49
49
  const deriveProduct = t.mock.fn((one, two) => one * two);
@@ -101,9 +101,9 @@ test("derive", (t) => {
101
101
  });
102
102
 
103
103
  test("derive nested signals", (t) => {
104
- const [$value, setValue] = signal(5);
104
+ const [$value, setValue] = createState(5);
105
105
 
106
- const [$object, setObject] = signal({
106
+ const [$object, setObject] = createState({
107
107
  href: derive([$value], (value) => `/projects/${value}/test`),
108
108
  });
109
109
 
package/vite.config.js CHANGED
@@ -3,8 +3,6 @@ import { defineConfig } from "vite";
3
3
 
4
4
  export default defineConfig({
5
5
  build: {
6
- // minify: "terser",
7
- // minify: false,
8
6
  sourcemap: true,
9
7
 
10
8
  lib: {
@@ -16,13 +14,5 @@ export default defineConfig({
16
14
  name: "Dolla",
17
15
  formats: ["es"],
18
16
  },
19
- // rollupOptions: {
20
- // external: ["vue"],
21
- // output: {
22
- // globals: {
23
- // vue: "Vue",
24
- // },
25
- // },
26
- // },
27
17
  },
28
18
  });
package/dist/markup.d.ts DELETED
@@ -1,100 +0,0 @@
1
- import type { Dolla } from "./modules/dolla.js";
2
- import { MaybeSignal, type Signal } from "./signals.js";
3
- import type { Renderable, Stringable } from "./types.js";
4
- import { type ViewFunction, type ViewContext, type ViewResult } from "./view.js";
5
- export interface ElementContext {
6
- /**
7
- * The root Dolla instance this element belongs to.
8
- */
9
- root: Dolla;
10
- /**
11
- * Whether to create DOM nodes in the SVG namespace. An `<svg>` element will set this to true and pass it down to children.
12
- */
13
- isSVG?: boolean;
14
- }
15
- /**
16
- * Markup is a set of element metadata that hasn't been constructed into a MarkupNode yet.
17
- */
18
- export interface Markup {
19
- type: string | ViewFunction<any>;
20
- props?: Record<string, any>;
21
- children?: Markup[];
22
- }
23
- /**
24
- * A DOM node that has been constructed from a Markup object.
25
- */
26
- export interface MarkupNode {
27
- readonly node?: Node;
28
- readonly isMounted: boolean;
29
- mount(parent: Node, after?: Node): void;
30
- unmount(): void;
31
- }
32
- export declare function isMarkup(value: unknown): value is Markup;
33
- export declare function isNode(value: unknown): value is MarkupNode;
34
- export declare function toMarkup(renderables: Renderable | Renderable[]): Markup[];
35
- export interface MarkupAttributes {
36
- $text: {
37
- value: MaybeSignal<Stringable>;
38
- };
39
- $cond: {
40
- $predicate: Signal<any>;
41
- thenContent?: Renderable;
42
- elseContent?: Renderable;
43
- };
44
- $repeat: {
45
- $items: Signal<any[]>;
46
- keyFn: (value: any, index: number) => string | number | symbol;
47
- renderFn: ($item: Signal<any>, $index: Signal<number>, c: ViewContext) => ViewResult;
48
- };
49
- $observer: {
50
- signals: Signal<any>[];
51
- renderFn: (...items: any) => Renderable;
52
- };
53
- $outlet: {
54
- $children: Signal<MarkupNode[]>;
55
- };
56
- $node: {
57
- value: Node;
58
- };
59
- $portal: {
60
- content: Renderable;
61
- parent: Node;
62
- };
63
- [tag: string]: Record<string, any>;
64
- }
65
- export declare function createMarkup<T extends keyof MarkupAttributes>(type: T, attributes: MarkupAttributes[T], ...children: Renderable[]): Markup;
66
- export declare function createMarkup<I>(type: ViewFunction<I>, attributes?: I, ...children: Renderable[]): Markup;
67
- /**
68
- * Generate markup with HTML in a tagged template literal.
69
- */
70
- export declare const html: (strings: TemplateStringsArray, ...values: any[]) => Markup | Markup[];
71
- /**
72
- * Displays content conditionally. When `predicate` holds a truthy value, `thenContent` is displayed; when `predicate` holds a falsy value, `elseContent` is displayed.
73
- */
74
- export declare function cond(predicate: MaybeSignal<any>, thenContent?: Renderable, elseContent?: Renderable): Markup;
75
- /**
76
- * Calls `renderFn` for each item in `items`. Dynamically adds and removes views as items change.
77
- * The result of `keyFn` is used to compare items and decide if item was added, removed or updated.
78
- */
79
- 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;
80
- /**
81
- * Render `content` into a `parent` node anywhere in the page, rather than at its position in the view.
82
- */
83
- export declare function portal(parent: Node, content: Renderable): Markup;
84
- /**
85
- * A special kind of signal exclusively for storing references to DOM nodes.
86
- */
87
- export declare function createRef<T extends Node>(): Ref<T>;
88
- export declare function isRef<T extends Node>(value: any): value is Ref<T>;
89
- export interface Ref<T extends Node> extends Signal<T | undefined> {
90
- node: T | undefined;
91
- }
92
- /**
93
- * Construct Markup metadata into a set of MarkupNodes.
94
- */
95
- export declare function constructMarkup(elementContext: ElementContext, markup: Markup | Markup[]): MarkupNode[];
96
- /**
97
- * Combines one or more MarkupNodes into a single MarkupNode.
98
- */
99
- export declare function mergeNodes(nodes: MarkupNode[]): MarkupNode;
100
- export declare function isRenderable(value: unknown): value is Renderable;
@@ -1,111 +0,0 @@
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";
9
- export type Environment = "development" | "production";
10
- /**
11
- * Log type toggles. Each message category can be turned on or off or enabled only in a specific environment.
12
- */
13
- export type Loggles = {
14
- info: boolean | Environment;
15
- log: boolean | Environment;
16
- warn: boolean | Environment;
17
- error: boolean | Environment;
18
- };
19
- export interface Logger {
20
- info(...args: any[]): void;
21
- log(...args: any[]): void;
22
- warn(...args: any[]): void;
23
- error(...args: any[]): void;
24
- crash(error: Error): void;
25
- }
26
- export interface LoggerErrorContext {
27
- error: Error;
28
- loggerName: string;
29
- uid?: string;
30
- }
31
- export type LoggerOptions = {
32
- /**
33
- * Console object to use for logging (mostly for testing). Uses window.console by default.
34
- */
35
- console?: any;
36
- /**
37
- * Unique ID to print with logs. Makes it easier to track down messages from specific view instances.
38
- */
39
- uid?: string;
40
- };
41
- export declare class Dolla {
42
- #private;
43
- readonly http: HTTP;
44
- readonly language: Language;
45
- readonly render: Render;
46
- readonly router: Router;
47
- 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
- /**
58
- * True when the app is connected to a DOM node and displayed to the user.
59
- */
60
- get isMounted(): boolean;
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;
76
- mount(selector: string, view?: ViewFunction<any>): Promise<void>;
77
- mount(element: HTMLElement, view?: ViewFunction<any>): Promise<void>;
78
- unmount(): Promise<void>;
79
- /**
80
- * Registers a `callback` to run after `Dolla.mount` is called, before the app is mounted. If `callback` returns a Promise,
81
- * it will be awaited before mounting finishes. Use this to perform initial setup before the app is displayed to the user.
82
- */
83
- beforeMount(callback: () => void | Promise<void>): void;
84
- /**
85
- * Registers a `callback` to run after the app is mounted.
86
- */
87
- onMount(callback: () => void): void;
88
- /**
89
- * Registers a `callback` to run after `Dolla.unmount` is called, before the app is unmounted. If `callback` returns a Promise,
90
- * it will be awaited before unmounting finishes. Use this to perform cleanup.
91
- */
92
- beforeUnmount(callback: () => void | Promise<void>): void;
93
- /**
94
- * Registers a `callback` to run after the app is unmounted.
95
- */
96
- onUnmount(callback: () => void): void;
97
- /**
98
- * Update log type toggles. Values that are not passed will remain unchanged.
99
- */
100
- setLoggles(options: Partial<Loggles>): void;
101
- setLogFilter(filter: string | RegExp): void;
102
- createLogger(name: string | Signal<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;
111
- }
@@ -1,41 +0,0 @@
1
- import { type Signal } from "../signals.js";
2
- import type { Stringable } from "../types.js";
3
- import type { Dolla } from "./dolla.js";
4
- /**
5
- * An object where values are either a translated string or another nested Translation object.
6
- */
7
- type LocalizedStrings = Record<string, string | Record<string, string | Record<string, string | Record<string, string>>>>;
8
- export interface LanguageConfig {
9
- name: string;
10
- /**
11
- * Path to a JSON file with translated strings for this language.
12
- */
13
- path?: string;
14
- /**
15
- * A callback function that returns a Promise that resolves to the translation object for this language.
16
- */
17
- fetch?: () => Promise<LocalizedStrings>;
18
- }
19
- export type LanguageSetupOptions = {
20
- /**
21
- * Default language to load on startup
22
- */
23
- initialLanguage?: string | null;
24
- languages: LanguageConfig[];
25
- };
26
- export declare class Language {
27
- #private;
28
- $current: Signal<string | undefined>;
29
- constructor(dolla: Dolla);
30
- get supportedLanguages(): string[];
31
- setup(options: LanguageSetupOptions): void;
32
- setLanguage(name: string): Promise<void>;
33
- /**
34
- * Returns a Signal containing the value at `key`.
35
-
36
- * @param key - Key to the translated value.
37
- * @param values - A map of {{placeholder}} names and the values to replace them with.
38
- */
39
- t(key: string, values?: Record<string, Stringable | Signal<Stringable>>): Signal<string>;
40
- }
41
- export {};
@@ -1,17 +0,0 @@
1
- import type { Dolla } from "./dolla.js";
2
- export declare class Render {
3
- #private;
4
- constructor(dolla: Dolla);
5
- /**
6
- * Queues a callback to run in the next render batch.
7
- * Running your DOM mutations in update callbacks reduces layout thrashing.
8
- * Returns a Promise that resolves once the callback has run.
9
- */
10
- update(callback: () => void, key?: string): Promise<void>;
11
- /**
12
- * Queues a callback that reads DOM information to run after the next render batch,
13
- * ensuring all writes have been performed before reading.
14
- * Returns a Promise that resolves once the callback has run.
15
- */
16
- read(callback: () => void): Promise<void>;
17
- }