@manyducks.co/dolla 2.0.0-alpha.9 → 3.0.0

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 (90) hide show
  1. package/README.md +132 -573
  2. package/dist/core/context.d.ts +23 -0
  3. package/dist/core/debug.d.ts +19 -0
  4. package/dist/core/index.d.ts +24 -0
  5. package/dist/core/markup/helpers.d.ts +34 -0
  6. package/dist/core/markup/html.d.ts +3 -0
  7. package/dist/core/markup/html.test.d.ts +1 -0
  8. package/dist/core/markup/nodes/dom.d.ts +14 -0
  9. package/dist/core/markup/nodes/dynamic.d.ts +16 -0
  10. package/dist/core/markup/nodes/element.d.ts +14 -0
  11. package/dist/core/markup/nodes/portal.d.ts +15 -0
  12. package/dist/core/markup/nodes/repeat.d.ts +21 -0
  13. package/dist/core/markup/nodes/view.d.ts +17 -0
  14. package/dist/core/markup/scheduler.d.ts +1 -0
  15. package/dist/core/markup/types.d.ts +62 -0
  16. package/dist/core/markup/utils.d.ts +22 -0
  17. package/dist/core/markup/utils.test.d.ts +1 -0
  18. package/dist/core/ref.d.ts +13 -0
  19. package/dist/core/root.d.ts +36 -0
  20. package/dist/core/signals.d.ts +70 -0
  21. package/dist/core/signals.test.d.ts +1 -0
  22. package/dist/core/symbols.d.ts +2 -0
  23. package/dist/core-BLkJ-xuh.js +242 -0
  24. package/dist/core-BLkJ-xuh.js.map +1 -0
  25. package/dist/http/index.d.ts +43 -0
  26. package/dist/http.js +90 -0
  27. package/dist/http.js.map +1 -0
  28. package/dist/index.js +4 -1428
  29. package/dist/jsx-dev-runtime.d.ts +4 -2
  30. package/dist/jsx-dev-runtime.js +12 -16
  31. package/dist/jsx-dev-runtime.js.map +1 -1
  32. package/dist/jsx-runtime.d.ts +5 -3
  33. package/dist/jsx-runtime.js +17 -18
  34. package/dist/jsx-runtime.js.map +1 -1
  35. package/dist/router/index.d.ts +4 -0
  36. package/dist/router/matcher.test.d.ts +1 -0
  37. package/dist/router/router.d.ts +23 -0
  38. package/dist/router/router.test.d.ts +1 -0
  39. package/dist/router/store.d.ts +12 -0
  40. package/dist/router/types.d.ts +152 -0
  41. package/dist/router/utils.d.ts +99 -0
  42. package/dist/router/utils.test.d.ts +1 -0
  43. package/dist/router.js +429 -0
  44. package/dist/router.js.map +1 -0
  45. package/dist/signals-CMJPGr_M.js +354 -0
  46. package/dist/signals-CMJPGr_M.js.map +1 -0
  47. package/dist/translate/index.d.ts +82 -0
  48. package/dist/translate.js +125 -0
  49. package/dist/translate.js.map +1 -0
  50. package/dist/types.d.ts +83 -29
  51. package/dist/utils.d.ts +46 -12
  52. package/dist/utils.test.d.ts +1 -0
  53. package/dist/view-cBN-hn_T.js +360 -0
  54. package/dist/view-cBN-hn_T.js.map +1 -0
  55. package/dist/virtual/index.d.ts +1 -0
  56. package/dist/virtual/list.d.ts +53 -0
  57. package/index.d.ts +2 -2
  58. package/package.json +34 -17
  59. package/build.js +0 -34
  60. package/dist/index.d.ts +0 -21
  61. package/dist/index.js.map +0 -1
  62. package/dist/markup.d.ts +0 -108
  63. package/dist/modules/dolla.d.ts +0 -111
  64. package/dist/modules/http.d.ts +0 -57
  65. package/dist/modules/i18n.d.ts +0 -59
  66. package/dist/modules/render.d.ts +0 -17
  67. package/dist/modules/router.d.ts +0 -152
  68. package/dist/nodes/cond.d.ts +0 -26
  69. package/dist/nodes/html.d.ts +0 -31
  70. package/dist/nodes/observer.d.ts +0 -29
  71. package/dist/nodes/outlet.d.ts +0 -22
  72. package/dist/nodes/portal.d.ts +0 -19
  73. package/dist/nodes/repeat.d.ts +0 -34
  74. package/dist/nodes/text.d.ts +0 -19
  75. package/dist/passthrough-9kwwjgWk.js +0 -1279
  76. package/dist/passthrough-9kwwjgWk.js.map +0 -1
  77. package/dist/routing.d.ts +0 -79
  78. package/dist/state.d.ts +0 -101
  79. package/dist/typeChecking.d.ts +0 -191
  80. package/dist/view.d.ts +0 -65
  81. package/dist/views/default-crash-view.d.ts +0 -18
  82. package/dist/views/passthrough.d.ts +0 -5
  83. package/notes/context-vars.md +0 -21
  84. package/notes/readme-scratch.md +0 -222
  85. package/notes/route-middleware.md +0 -42
  86. package/notes/scratch.md +0 -233
  87. package/notes/views.md +0 -195
  88. package/tests/state.test.js +0 -135
  89. package/vite.config.js +0 -28
  90. /package/dist/{routing.test.d.ts → core/context.test.d.ts} +0 -0
@@ -1,191 +0,0 @@
1
- type TypeNames = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "null" | "array" | "class" | "promise" | "NaN";
2
- /**
3
- * Extends `typeof` operator with more specific and useful type distinctions.
4
- */
5
- export declare function typeOf(value: unknown): TypeNames;
6
- /**
7
- * Throws a TypeError unless `condition` is truthy.
8
- *
9
- * @param condition - Value whose truthiness is in question.
10
- * @param errorMessage - Optional message for the thrown TypeError.
11
- */
12
- export declare function assert(condition: any, errorMessage?: string): void;
13
- /**
14
- * Returns true if `value` is an array.
15
- */
16
- export declare function isArray(value: unknown): value is Array<unknown>;
17
- /**
18
- * Throws an error if `value` is not an array.
19
- */
20
- export declare function assertArray(value: unknown, errorMessage?: string): value is Array<unknown>;
21
- /**
22
- * Returns a function that takes a `value` and ensures that it is an array for which `check` returns true for every item.
23
- *
24
- * @param check - Function to check items against.
25
- */
26
- export declare function isArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];
27
- /**
28
- * Returns true when `value` is an array and `check` returns true for every item.
29
- *
30
- * @param check - Function to check items against.
31
- * @param value - A possible array.
32
- */
33
- export declare function isArrayOf<T>(check: (item: unknown) => boolean, value: unknown): value is T[];
34
- /**
35
- * Returns a function that takes a `value` and throws a TypeError unless it is an array for which `check` returns true for every item.
36
- *
37
- * @param check - Function to check items against.
38
- */
39
- export declare function assertArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];
40
- /**
41
- * Throws a TypeError unless `value` is an array and `check` returns true for every item.
42
- *
43
- * @param check - Function to check items against.
44
- * @param value - A possible array.
45
- * @param errorMessage - A custom error message.
46
- */
47
- export declare function assertArrayOf<T>(check: (item: unknown) => boolean, value: unknown, errorMessage?: string): value is T[];
48
- /**
49
- * Returns true if `value` is equal to `true` or `false`.
50
- */
51
- export declare function isBoolean(value: unknown): value is boolean;
52
- /**
53
- * Throws a TypeError unless `value` is equal to `true` or `false`.
54
- */
55
- export declare function assertBoolean(value: unknown, errorMessage?: string): value is boolean;
56
- /**
57
- * Returns true if `value` is a string.
58
- */
59
- export declare function isString(value: unknown): value is string;
60
- /**
61
- * Throws a TypeError unless `value` is a string.
62
- */
63
- export declare function assertString(value: unknown, errorMessage?: string): value is string;
64
- /**
65
- * Returns true if `value` is a function (but not a class).
66
- */
67
- export declare function isFunction<T = (...args: unknown[]) => unknown>(value: unknown): value is T;
68
- /**
69
- * Throws a TypeError unless `value` is a function.
70
- */
71
- export declare function assertFunction<T = (...args: unknown[]) => unknown>(value: unknown, errorMessage?: string): value is T;
72
- /**
73
- * Returns true if `value` is a number.
74
- */
75
- export declare function isNumber(value: unknown): value is number;
76
- /**
77
- * Throws a TypeError unless `value` is a number.
78
- */
79
- export declare function assertNumber(value: unknown, errorMessage?: string): value is number;
80
- /**
81
- * Returns true if `value` implements the Promise protocol.
82
- * This matches true instances of Promise as well as any object that
83
- * implements `next`, `catch` and `finally` methods.
84
- *
85
- * To strictly match instances of Promise, use `isInstanceOf(Promise)`.
86
- */
87
- export declare function isPromise<T = unknown>(value: unknown): value is Promise<T>;
88
- /**
89
- * Throws a TypeError unless `value` implements the Promise protocol.
90
- * This matches true instances of Promise as well as any object that
91
- * implements `next`, `catch` and `finally` methods.
92
- *
93
- * To strictly allow only instances of Promise, use `Type.assertInstanceOf(Promise)`.
94
- */
95
- export declare function assertPromise<T = unknown>(value: unknown, errorMessage?: string): value is Promise<T>;
96
- /**
97
- * Returns true if `value` is a class.
98
- */
99
- export declare function isClass(value: unknown): value is {
100
- new (): unknown;
101
- };
102
- /**
103
- * Throws a TypeError unless `value` is a class.
104
- */
105
- export declare function assertClass(value: unknown, errorMessage?: string): value is {
106
- new (): unknown;
107
- };
108
- /**
109
- * Returns a function that takes a `value` and returns true if `value` is an instance of `constructor`.
110
- *
111
- * @param constructor - The constructor a value must be an instance of to match.
112
- */
113
- export declare function isInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;
114
- /**
115
- * Returns `true` if `value` is an instance of `constructor`.
116
- *
117
- * @param constructor - The constructor `value` must be an instance of.
118
- * @param value - A value that may be an instance of `constructor`.
119
- */
120
- export declare function isInstanceOf<T extends Function>(constructor: T, value: unknown): value is T;
121
- /**
122
- * Returns a function that takes a `value` and throws a TypeError unless `value` is an instance of `constructor`.
123
- *
124
- * @param constructor - The constructor a value must be an instance of to match.
125
- */
126
- export declare function assertInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;
127
- /**
128
- * Throws a TypeError unless `value` is an instance of `constructor`.
129
- *
130
- * @param constructor - The constructor `value` must be an instance of.
131
- * @param value - A value that may be an instance of `constructor`.
132
- * @param errorMessage - A custom error message for when the assertion fails.
133
- */
134
- export declare function assertInstanceOf<T extends Function>(constructor: T, value: unknown, errorMessage?: string): value is T;
135
- /**
136
- * Returns true if `value` is a Map.
137
- */
138
- export declare function isMap<K = unknown, V = unknown>(value: any): value is Map<K, V>;
139
- /**
140
- * Throws a TypeError unless `value` is a Map.
141
- */
142
- export declare function assertMap<K = unknown, V = unknown>(value: any, errorMessage?: string): value is Map<K, V>;
143
- /**
144
- * Returns true if `value` is a Set.
145
- */
146
- export declare function isSet<T = unknown>(value: any): value is Set<T>;
147
- /**
148
- * Throws a TypeError if `value` is not a Set.
149
- */
150
- export declare function assertSet<T = unknown>(value: any, errorMessage?: string): value is Set<T>;
151
- /**
152
- * Returns true if `value` implements the Iterable protocol.
153
- */
154
- export declare function isIterable<T>(value: any): value is Iterable<T>;
155
- /**
156
- * Throws a TypeError unless `value` implements the Iterable protocol.
157
- */
158
- export declare function assertIterable<T>(value: any, errorMessage?: string): value is Iterable<T>;
159
- /**
160
- * Returns true if `value` is a plain JavaScript object.
161
- */
162
- export declare function isObject(value: unknown): value is Record<string | number | symbol, unknown>;
163
- /**
164
- * Throws a TypeError unless `value` is a plain JavaScript object.
165
- */
166
- export declare function assertObject(value: unknown, errorMessage?: string): value is object;
167
- /**
168
- * Returns true if `value` is equal to `null`.
169
- */
170
- export declare function isNull(value: unknown): value is null;
171
- /**
172
- * Throws a TypeError unless `value` is equal to `null`.
173
- */
174
- export declare function assertNull(value: unknown, errorMessage?: string): value is null;
175
- /**
176
- * Returns true if `value` is equal to `undefined`.
177
- */
178
- export declare function isUndefined(value: unknown): value is undefined;
179
- /**
180
- * Throws a TypeError unless `value` is equal to `undefined`.
181
- */
182
- export declare function assertUndefined(value: unknown, errorMessage?: string): value is undefined;
183
- /**
184
- * Returns true if `value` is equal to `null` or `undefined`.
185
- */
186
- export declare function isEmpty(value: unknown): value is void;
187
- /**
188
- * Throws a TypeError unless `value` is equal to `null` or `undefined`.
189
- */
190
- export declare function assertEmpty(value: unknown, errorMessage?: string): value is void;
191
- export {};
package/dist/view.d.ts DELETED
@@ -1,65 +0,0 @@
1
- import { type MarkupNode, type ElementContext, type Markup } from "./markup.js";
2
- import type { Logger } from "./modules/dolla.js";
3
- import { type MaybeState, State, type StateValues, type StopFunction } from "./state.js";
4
- /**
5
- * Any valid value that a View can return.
6
- */
7
- export type ViewResult = Node | State<any> | Markup | Markup[] | null;
8
- export type ViewFunction<P> = (props: P, context: ViewContext) => ViewResult;
9
- /**
10
- * A view that has been constructed into DOM nodes.
11
- */
12
- export interface ViewNode extends MarkupNode {
13
- /**
14
- * Take a ViewFunction and render it as a child of this view.
15
- */
16
- setChildView(view: ViewFunction<{}>): ViewNode;
17
- }
18
- export interface ViewContext extends Logger {
19
- /**
20
- * A string ID unique to this view.
21
- */
22
- readonly uid: string;
23
- /**
24
- * Sets a context variable. Context variables are accessible on the same context and from those of child views.
25
- */
26
- set<T>(key: string | symbol, value: T): void;
27
- /**
28
- * Gets the value of a context variable. Returns null if the variable is not set.
29
- */
30
- get<T>(key: string | symbol): T | null;
31
- /**
32
- * Returns an object of all variables stored on this context.
33
- */
34
- getAll(): Record<string | symbol, unknown>;
35
- /**
36
- * Sets the name of the view's built in logger.
37
- */
38
- setName(name: string): void;
39
- /**
40
- * Registers a callback to run just before this view is mounted. DOM nodes are not yet attached to the page.
41
- */
42
- beforeMount(callback: () => void): void;
43
- /**
44
- * Registers a callback to run just after this view is mounted.
45
- */
46
- onMount(callback: () => void): void;
47
- /**
48
- * Registers a callback to run just before this view is unmounted. DOM nodes are still attached to the page.
49
- */
50
- beforeUnmount(callback: () => void): void;
51
- /**
52
- * Registers a callback to run just after this view is unmounted.
53
- */
54
- onUnmount(callback: () => void): void;
55
- /**
56
- * Watch a set of states. The callback is called when any of the states receive a new value.
57
- * Watchers will be automatically stopped when this view is unmounted.
58
- */
59
- watch<T extends MaybeState<any>[]>(states: [...T], callback: (...values: StateValues<T>) => void): StopFunction;
60
- /**
61
- * Returns a Markup element that displays this view's children.
62
- */
63
- outlet(): Markup;
64
- }
65
- export declare function constructView<P>(elementContext: ElementContext, view: ViewFunction<P>, props: P, children?: Markup[]): ViewNode;
@@ -1,18 +0,0 @@
1
- /**
2
- * Props passed to the crash view when a crash occurs.
3
- */
4
- export type CrashViewProps = {
5
- /**
6
- * JavaScript Error object.
7
- */
8
- error: Error;
9
- /**
10
- * A string to identify the logger that reported this error.
11
- */
12
- loggerName: string;
13
- /**
14
- * Unique identifier to pinpoint the specific view that reported the crash.
15
- */
16
- uid?: string;
17
- };
18
- export declare function DefaultCrashView(props: CrashViewProps): import("../markup.js").Markup | import("../markup.js").Markup[];
@@ -1,5 +0,0 @@
1
- import { type ViewContext } from "../view.js";
2
- /**
3
- * A utility view that simply displays its children.
4
- */
5
- export declare function Passthrough(_: {}, ctx: ViewContext): import("../markup.js").Markup;
@@ -1,21 +0,0 @@
1
- # Idea: Context Variables
2
-
3
- In designing how Dolla's version of 'context' works, I've been going through a few different ideas. The simplest seems to be the ability to store _context variables_ that, once set, are accessible on the same context or any child context.
4
-
5
- ```js
6
- function SomeView(props, ctx) {
7
- ctx.set("key", 5);
8
-
9
- // ... and in a child view do
10
- ctx.get("key");
11
- // which returns null if the value isn't present.
12
- // It's like localStorage for the view tree.
13
- }
14
- ```
15
-
16
- They can be typed, but always with a possibility to return null.
17
-
18
- ```js
19
- const value = ctx.get<number>("key");
20
- // value is number | null to force the programmer to check it.
21
- ```
@@ -1,222 +0,0 @@
1
- # README
2
-
3
- > This note will eventually become the new README. Here I'm laying out my ideal framework API.
4
-
5
- A basic component.
6
-
7
- ```jsx
8
- import Dolla, { createState, derive } from "@manyducks.co/dolla";
9
-
10
- function ExampleView(props, ctx) {
11
- const [$count, setCount] = createState(5);
12
- const $doubled = derive([$count], (n) => n * 2);
13
-
14
- ctx.watch([$count], (count) => {
15
- ctx.log("value of count is now %n", count);
16
- });
17
-
18
- return <p>{$count}</p>;
19
- }
20
-
21
- Dolla.mount(document.body, ExampleView);
22
- ```
23
-
24
- <details open>
25
- <summary>
26
- <h2>Signals API</h2>
27
- </summary>
28
-
29
- The signals API. Dolla's signals use explicit tracking, meaning any function where signal values are tracked take an array of the signals you want to track. This way you know exactly what depends on what at a glance without any kind of hidden tracking logic behind the scenes. You are free to `.get()` the value of a signal without worrying about untracking it first.
30
-
31
- ```jsx
32
- import { createState } from "@manyducks.co/dolla";
33
-
34
- const [$count, setCount] = createState(256);
35
-
36
- $count.get(); // 256; returns the current value
37
-
38
- const stop = $count.watch((value) => {
39
- // Runs once immediately, then again whenever the value changes.
40
- });
41
-
42
- setCount(512); // Update the value of $count. The new value is set and all watchers run synchronously.
43
-
44
- stop(); // Stop watching for changes.
45
- ```
46
-
47
- That is the basic signal API. Signals are all about composability. Here are some more advanced ways of working with them:
48
-
49
- ```jsx
50
- import { createState, toState, valueOf, derive } from "@manyducks.co/dolla";
51
-
52
- const [$count, setCount] = createState(72);
53
-
54
- // Returns the value of the signal passed in. If the value is not a signal it is returned as is.
55
- const count = valueOf($count);
56
- const bool = valueOf(true);
57
-
58
- // Creates a signal containing the value passed in. If the value is already a signal it is returned as is.
59
- const $bool = toState(true);
60
- const $anotherCount = toState($count);
61
-
62
- // Derive a new signal from the value of another. Whenever $count changes, $doubled will follow.
63
- const $doubled = derive([$count], (count) => count * 2);
64
-
65
- // Derive a new signal from the values of several others. When any value in the list changes, $sum will be recomputed.
66
- const $sum = derive([$count, $doubled], (count, doubled) => count + doubled);
67
- ```
68
-
69
- The API if we call it State instead of Signal to distance from the Signal object in standardization process.
70
-
71
- ```jsx
72
- import { createState, toState, valueOf, derive } from "@manyducks.co/dolla";
73
-
74
- const [$count, setCount] = createState(72);
75
-
76
- // Returns the value of the signal passed in. If the value is not a signal it is returned as is.
77
- const count = valueOf($count);
78
- const bool = valueOf(true);
79
-
80
- // Creates a signal containing the value passed in. If the value is already a signal it is returned as is.
81
- const $bool = toState(true);
82
- const $anotherCount = toState($count);
83
-
84
- // Derive a new signal from the value of another. Whenever $count changes, $doubled will follow.
85
- const $doubled = derive([$count], (count) => count * 2);
86
-
87
- // Derive a new signal from the values of several others. When any value in the list changes, $sum will be recomputed.
88
- const $sum = derive([$count, $doubled], (count, doubled) => count + doubled);
89
- ```
90
-
91
- States also come in a settable variety, with the setter included on the same object. Sometimes you want to pass around a two-way binding and this is what SettableState is for.
92
-
93
- ```jsx
94
- import { createSettableState, fromSettable, toSettable } from "@manyducks.co/dolla";
95
-
96
- // Settable states have their setter included.
97
- const $$value = createSettableState("Test");
98
- $$value.set("New Value");
99
-
100
- // They can also be split into a State and Setter
101
- const [$value, setValue] = fromSettableState($$value);
102
-
103
- // And a State and Setter can be combined into a SettableState.
104
- const $$otherValue = toSettableState($value, setValue);
105
-
106
- // Or discard the setter and make it read-only using the good old toState function:
107
- const $value = toState($$value);
108
- ```
109
-
110
- Alternative API
111
-
112
- ```jsx
113
- import { State } from "@manyducks.co/dolla";
114
-
115
- const [$count, setCount] = State(72);
116
-
117
- const count = State.unwrap($count);
118
- const bool = State.unwrap(true);
119
-
120
- const $bool = State.wrap(true);
121
- const $sameCount = State.wrap($count);
122
-
123
- const $doubled = State.from([$count], (count) => count * 2);
124
-
125
- const $sum = State.from([$count, $doubled], (count, doubled) => count + doubled);
126
- ```
127
-
128
- Yet another
129
-
130
- ```jsx
131
- import Dolla from "@manyducks.co/dolla";
132
-
133
- const [$count, setCount] = Dolla.state(72);
134
-
135
- const count = Dolla.get($count);
136
- const bool = Dolla.get(true);
137
-
138
- const $bool = Dolla.toState(true);
139
- const $sameCount = Dolla.toState($count);
140
-
141
- const $doubled = Dolla.computed([$count], (count) => count * 2);
142
- const $sum = Dolla.computed([$count, $doubled], (count, doubled) => count + doubled);
143
-
144
- // or
145
-
146
- import { state, computed, get, toState } from "@manyducks.co/dolla";
147
-
148
- const [$count, setCount] = state(72);
149
-
150
- const count = get($count);
151
- const bool = get(true);
152
-
153
- const $bool = toState(true);
154
- const $sameCount = toState($count);
155
-
156
- const $doubled = computed([$count], (count) => count * 2);
157
- const $sum = computed([$count, $doubled], (count, doubled) => count + doubled);
158
- ```
159
-
160
- Settable signals:
161
-
162
- ```jsx
163
- import { createSettableState, createSetter, toSettableSignal, fromSettableSignal } from "@manyducks.co/dolla";
164
-
165
- // Create a SettableSignal, which is basically a signal and its setter combined into a single object.
166
- const $$settable = createSettableState("Example");
167
-
168
- // The basic API is identical...
169
- $$settable.get();
170
- const stop = $$settable.watch((value) => {
171
- // ...
172
- });
173
- stop();
174
-
175
- // ... except for the addition of a setter.
176
- $$settable.set("Set me directly");
177
-
178
- // When you already have a signal and a setter, they can be combined into one.
179
- const $$count = toSettableSignal($count, setCount);
180
-
181
- // This updates the original $signal value.
182
- $$count.set(386);
183
-
184
- // TODO: You can also split a SettableSignal into a signal and its setter.
185
- const [$readable, setReadable] = fromSettableSignal($$settable);
186
-
187
- // Create a custom setter. Calling this will cap the value to 100.
188
- const setCountBounded = createSetter($count, (next, current) => {
189
- return Math.min(100, next);
190
- });
191
-
192
- setCountBounded((current) => {
193
- return current + 1;
194
- });
195
-
196
- // Or make a proxy $$doubled -- but would you actually want to proxy things like this?
197
- const [$count, setCount] = createState(5);
198
- const $doubled = derive([$count], (count) => count * 2);
199
- const $$doubled = toSettableSignal(
200
- $doubled,
201
- createSetter($doubled, (next, current) => {
202
- setCount(next * 2);
203
- }),
204
- );
205
- ```
206
-
207
- I'm not really sure we need all of this. On the chopping block:
208
-
209
- - The entire concept of settable signals
210
- - `createSettableState`
211
- - `toSettableSignal`
212
- - `fromSettableSignal`
213
- - `createSetter`
214
-
215
- This makes the entire API just four functions:
216
-
217
- - `createState`
218
- - `derive`
219
- - `toState`
220
- - `valueOf`
221
-
222
- </details>
@@ -1,42 +0,0 @@
1
- # Router Middleware
2
-
3
- Allow handling route guards, preloading, etc with per-route middleware. When a route is matched, all middleware from higher layers are run again.
4
-
5
- ```js
6
- Dolla.router.setup({
7
- middleware: [/* does it make sense to have global middleware? */]
8
- routes: [
9
- { path: "/login", middleware: [auth] },
10
- { path: "/", middleware: [auth], routes: [{ path: "/example", view: ExampleView }] }
11
- ]
12
- });
13
-
14
- async function auth(ctx) {
15
- // This check can be implemented however it needs to be for the app.
16
- const authed = await isAuthorized();
17
-
18
- if (ctx.path === "/login") {
19
- if (authed) {
20
- ctx.redirect("/");
21
- }
22
- } else {
23
- if (!authed) {
24
- ctx.redirect("/login");
25
- }
26
- }
27
- // If no redirect has happened and nothing has been returned then we're clear to proceed.
28
- }
29
-
30
- // A middleware can also return Markup to stay on the URL but show something different.
31
- async function randomVisitor(ctx) {
32
- if (Math.random() > 0.99) {
33
- return <LuckyVisitorView />
34
- }
35
- }
36
-
37
- // Or preload async data and set a context variable before navigating.
38
- async function preload(ctx) {
39
- const data = await fetchData();
40
- ctx.set("data", data);
41
- }
42
- ```