@manyducks.co/dolla 2.0.0-alpha.64 → 2.0.0-alpha.65

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 (55) hide show
  1. package/dist/core/app.d.ts +24 -0
  2. package/dist/core/index.d.ts +2 -2
  3. package/dist/core/nodes/element.d.ts +1 -0
  4. package/dist/core/scheduler.d.ts +12 -4
  5. package/dist/core/signals.d.ts +10 -9
  6. package/dist/hooks/index.d.ts +2 -2
  7. package/dist/hooks.js +1 -1
  8. package/dist/hooks.js.map +1 -1
  9. package/dist/http.js +1 -1
  10. package/dist/i18n.js +3 -3
  11. package/dist/index-Bh8JrCt1.js +556 -0
  12. package/dist/index-Bh8JrCt1.js.map +1 -0
  13. package/dist/index.js +113 -70
  14. package/dist/index.js.map +1 -1
  15. package/dist/jsx-dev-runtime.js +1 -1
  16. package/dist/jsx-runtime.js +1 -1
  17. package/dist/{logger-B7RBYtzP.js → logger-BuZRMjzE.js} +5 -5
  18. package/dist/{logger-B7RBYtzP.js.map → logger-BuZRMjzE.js.map} +1 -1
  19. package/dist/markup-DsJHUuod.js +1179 -0
  20. package/dist/markup-DsJHUuod.js.map +1 -0
  21. package/dist/router/hooks.d.ts +2 -0
  22. package/dist/router/index.d.ts +1 -0
  23. package/dist/router/router.d.ts +1 -0
  24. package/dist/router.js +3 -5
  25. package/dist/router.js.map +1 -1
  26. package/dist/{signals-DbDmN2gr.js → signals-BDlRtifZ.js} +264 -255
  27. package/dist/signals-BDlRtifZ.js.map +1 -0
  28. package/dist/typeChecking-D0-H8_Xm.js +62 -0
  29. package/dist/{typeChecking-CbltMOUt.js.map → typeChecking-D0-H8_Xm.js.map} +1 -1
  30. package/dist/utils.d.ts +5 -0
  31. package/docs/components.md +21 -0
  32. package/docs/hooks.md +3 -3
  33. package/docs/signals.md +67 -53
  34. package/docs/stores.md +13 -4
  35. package/package.json +4 -4
  36. package/dist/core/mount.d.ts +0 -15
  37. package/dist/core/mount.test.d.ts +0 -0
  38. package/dist/markup-DeZDwQ9F.js +0 -1117
  39. package/dist/markup-DeZDwQ9F.js.map +0 -1
  40. package/dist/router-C35XmU3k.js +0 -543
  41. package/dist/router-C35XmU3k.js.map +0 -1
  42. package/dist/signals-DbDmN2gr.js.map +0 -1
  43. package/dist/typeChecking-CbltMOUt.js +0 -71
  44. package/docs/state.md +0 -141
  45. package/examples/webcomponent/index.html +0 -14
  46. package/examples/webcomponent/main.js +0 -165
  47. package/notes/TODO.md +0 -6
  48. package/notes/context-routes.md +0 -61
  49. package/notes/custom-nodes.md +0 -17
  50. package/notes/effection-idea.md +0 -34
  51. package/notes/mixins.md +0 -22
  52. package/notes/molecule.md +0 -35
  53. package/notes/readme-scratch.md +0 -260
  54. package/notes/route-middleware.md +0 -42
  55. package/notes/stores.md +0 -79
package/notes/molecule.md DELETED
@@ -1,35 +0,0 @@
1
- Like `compose` but it takes an initial value and a function that can set its value asynchronously. Its callback is a tracking context, so it will be re-run when signals called within are updated.
2
-
3
- ```ts
4
- interface MoleculeGetter<T> {
5
- (): T;
6
- <X>(source: MaybeReactive<X>): X;
7
- }
8
-
9
- interface MoleculeSetter<T> {
10
- (next: T): void;
11
- }
12
-
13
- interface MoleculeFunction<T> {
14
- (get: MoleculeGetter<T>, set: MoleculeSetter<T>): void | (() => void);
15
- }
16
-
17
- function molecule<T>(initialValue: T, fn: MoleculeFunction<T>) {}
18
-
19
- const value = molecule(5, (get, set) => {
20
- // get() returns the current value stored in this hadron
21
- // get(reactive) returns the value of that reactive and tracks it (== reactive.get())
22
- // set(value) updates the value stored in this hadron
23
- // This function will not be called unless there is at least one observer.
24
-
25
- let interval = setInterval(() => {
26
- set(get() + 1);
27
- }, 1000);
28
-
29
- // Can return a cleanup function to run between invocations.
30
- // Also called when the last observer stops observing.
31
- return () => {
32
- clearInterval(interval);
33
- };
34
- });
35
- ```
@@ -1,260 +0,0 @@
1
- # README
2
-
3
- ```jsx
4
- import { mount, atom, html } from "@manyducks.co/atomic";
5
-
6
- function Home() {
7
- return html` <h1>This is the home page!</h1> `;
8
- }
9
-
10
- // mount to DOM element
11
- mount(Home, document.body);
12
-
13
- // render to string
14
- const string = await render(Home, "/the/path/here");
15
- ```
16
-
17
- ---
18
-
19
- > This note will eventually become the new README. Here I'm laying out my ideal framework API.
20
-
21
- A basic component.
22
-
23
- ```jsx
24
- import { mount, state, derive, batch } from "@manyducks.co/dolla";
25
-
26
- function ExampleView(props, ctx) {
27
- // Signals: state, derive, effect and batch
28
-
29
- const count = state(5);
30
-
31
- const doubled = derive(() => count.value * 2);
32
-
33
- batch(() => {
34
- // Perform multiple updates in one go and commit at the end.
35
- });
36
-
37
- // If effect is called in the body of a view function it will be cleaned up automatically with the view.
38
- ctx.effect(() => {
39
- console.log(nested.value);
40
- });
41
-
42
- // Emit and listen for context events.
43
- ctx.on("event", (e, ...args) => {
44
- e.cancel();
45
- });
46
- ctx.emit("event", ...args);
47
-
48
- // Get and set context values.
49
- ctx.set("context value", 5);
50
- ctx.get("context value");
51
-
52
- // Provide and use a store.
53
- const store = ctx.provide(someStore); // provide creates a new instance attached to this view and returns it.
54
- const store = ctx.use(someStore);
55
-
56
- return <p>{count}</p>;
57
- }
58
-
59
- mount(ExampleView, document.body);
60
- ```
61
-
62
- <details open>
63
- <summary>
64
- <h2>Signals API</h2>
65
- </summary>
66
-
67
- 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.
68
-
69
- ```jsx
70
- import { createState } from "@manyducks.co/dolla";
71
-
72
- const [$count, setCount] = createState(256);
73
-
74
- $count.get(); // 256; returns the current value
75
-
76
- const stop = $count.watch((value) => {
77
- // Runs once immediately, then again whenever the value changes.
78
- });
79
-
80
- setCount(512); // Update the value of $count. The new value is set and all watchers run synchronously.
81
-
82
- stop(); // Stop watching for changes.
83
- ```
84
-
85
- That is the basic signal API. Signals are all about composability. Here are some more advanced ways of working with them:
86
-
87
- ```jsx
88
- import { createState, toState, valueOf, derive } from "@manyducks.co/dolla";
89
-
90
- const [$count, setCount] = createState(72);
91
-
92
- // Returns the value of the signal passed in. If the value is not a signal it is returned as is.
93
- const count = valueOf($count);
94
- const bool = valueOf(true);
95
-
96
- // Creates a signal containing the value passed in. If the value is already a signal it is returned as is.
97
- const $bool = toState(true);
98
- const $anotherCount = toState($count);
99
-
100
- // Derive a new signal from the value of another. Whenever $count changes, $doubled will follow.
101
- const $doubled = derive([$count], (count) => count * 2);
102
-
103
- // Derive a new signal from the values of several others. When any value in the list changes, $sum will be recomputed.
104
- const $sum = derive([$count, $doubled], (count, doubled) => count + doubled);
105
- ```
106
-
107
- The API if we call it State instead of Signal to distance from the Signal object in standardization process.
108
-
109
- ```jsx
110
- import { createState, toState, valueOf, derive } from "@manyducks.co/dolla";
111
-
112
- const [$count, setCount] = createState(72);
113
-
114
- // Returns the value of the signal passed in. If the value is not a signal it is returned as is.
115
- const count = valueOf($count);
116
- const bool = valueOf(true);
117
-
118
- // Creates a signal containing the value passed in. If the value is already a signal it is returned as is.
119
- const $bool = toState(true);
120
- const $anotherCount = toState($count);
121
-
122
- // Derive a new signal from the value of another. Whenever $count changes, $doubled will follow.
123
- const $doubled = derive([$count], (count) => count * 2);
124
-
125
- // Derive a new signal from the values of several others. When any value in the list changes, $sum will be recomputed.
126
- const $sum = derive([$count, $doubled], (count, doubled) => count + doubled);
127
- ```
128
-
129
- 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.
130
-
131
- ```jsx
132
- import { createSettableState, fromSettable, toSettable } from "@manyducks.co/dolla";
133
-
134
- // Settable states have their setter included.
135
- const $$value = createSettableState("Test");
136
- $$value.set("New Value");
137
-
138
- // They can also be split into a State and Setter
139
- const [$value, setValue] = fromSettableState($$value);
140
-
141
- // And a State and Setter can be combined into a SettableState.
142
- const $$otherValue = toSettableState($value, setValue);
143
-
144
- // Or discard the setter and make it read-only using the good old toState function:
145
- const $value = toState($$value);
146
- ```
147
-
148
- Alternative API
149
-
150
- ```jsx
151
- import { State } from "@manyducks.co/dolla";
152
-
153
- const [$count, setCount] = State(72);
154
-
155
- const count = State.unwrap($count);
156
- const bool = State.unwrap(true);
157
-
158
- const $bool = State.wrap(true);
159
- const $sameCount = State.wrap($count);
160
-
161
- const $doubled = State.from([$count], (count) => count * 2);
162
-
163
- const $sum = State.from([$count, $doubled], (count, doubled) => count + doubled);
164
- ```
165
-
166
- Yet another
167
-
168
- ```jsx
169
- import Dolla from "@manyducks.co/dolla";
170
-
171
- const [$count, setCount] = Dolla.state(72);
172
-
173
- const count = Dolla.get($count);
174
- const bool = Dolla.get(true);
175
-
176
- const $bool = Dolla.toState(true);
177
- const $sameCount = Dolla.toState($count);
178
-
179
- const $doubled = Dolla.computed([$count], (count) => count * 2);
180
- const $sum = Dolla.computed([$count, $doubled], (count, doubled) => count + doubled);
181
-
182
- // or
183
-
184
- import { state, computed, get, toState } from "@manyducks.co/dolla";
185
-
186
- const [$count, setCount] = state(72);
187
-
188
- const count = get($count);
189
- const bool = get(true);
190
-
191
- const $bool = toState(true);
192
- const $sameCount = toState($count);
193
-
194
- const $doubled = computed([$count], (count) => count * 2);
195
- const $sum = computed([$count, $doubled], (count, doubled) => count + doubled);
196
- ```
197
-
198
- Settable signals:
199
-
200
- ```jsx
201
- import { createSettableState, createSetter, toSettableSignal, fromSettableSignal } from "@manyducks.co/dolla";
202
-
203
- // Create a SettableSignal, which is basically a signal and its setter combined into a single object.
204
- const $$settable = createSettableState("Example");
205
-
206
- // The basic API is identical...
207
- $$settable.get();
208
- const stop = $$settable.watch((value) => {
209
- // ...
210
- });
211
- stop();
212
-
213
- // ... except for the addition of a setter.
214
- $$settable.set("Set me directly");
215
-
216
- // When you already have a signal and a setter, they can be combined into one.
217
- const $$count = toSettableSignal($count, setCount);
218
-
219
- // This updates the original $signal value.
220
- $$count.set(386);
221
-
222
- // TODO: You can also split a SettableSignal into a signal and its setter.
223
- const [$readable, setReadable] = fromSettableSignal($$settable);
224
-
225
- // Create a custom setter. Calling this will cap the value to 100.
226
- const setCountBounded = createSetter($count, (next, current) => {
227
- return Math.min(100, next);
228
- });
229
-
230
- setCountBounded((current) => {
231
- return current + 1;
232
- });
233
-
234
- // Or make a proxy $$doubled -- but would you actually want to proxy things like this?
235
- const [$count, setCount] = createState(5);
236
- const $doubled = derive([$count], (count) => count * 2);
237
- const $$doubled = toSettableSignal(
238
- $doubled,
239
- createSetter($doubled, (next, current) => {
240
- setCount(next * 2);
241
- }),
242
- );
243
- ```
244
-
245
- I'm not really sure we need all of this. On the chopping block:
246
-
247
- - The entire concept of settable signals
248
- - `createSettableState`
249
- - `toSettableSignal`
250
- - `fromSettableSignal`
251
- - `createSetter`
252
-
253
- This makes the entire API just four functions:
254
-
255
- - `createState`
256
- - `derive`
257
- - `toState`
258
- - `valueOf`
259
-
260
- </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
- ```
package/notes/stores.md DELETED
@@ -1,79 +0,0 @@
1
- # Stores
2
-
3
- Ideas for updating the API.
4
-
5
- ---
6
-
7
- What about a global stores registry? Basically just a global object you can import and register stores on, then get them later. Global (not scoped to views). You can still use `provide` and `get` on view contexts in the same exact way if you want scoped stores.
8
-
9
- This is a replacement for the current way of providing global stores on the Dolla object. The Dolla object is going away in future API versions.
10
-
11
- ```ts
12
- import { Stores, Views } from "@manyducks.co/dolla";
13
-
14
- Stores.provide(SomeStore, {
15
- /* options */
16
- });
17
-
18
- const some = Stores.get(SomeStore);
19
-
20
- const SomeStore = Stores.define(() => {});
21
-
22
- // Could also have views be defined this way.
23
- const SomeView = Views.define<SomeProps>((props, ctx) => {});
24
-
25
- // Register as a custom element.
26
- Views.register("some-view", SomeView);
27
- ```
28
-
29
- ---
30
-
31
- ```js
32
- function CounterStore(initialCount = 0, ctx) {
33
- const [$value, setValue] = createState(initialCount);
34
-
35
- ctx.on("counter:increment", (e) => {
36
- e.stop(); // Stop this event from bubbling up to counters at higher levels (if any).
37
- setValue((current) => current + 1);
38
- });
39
-
40
- ctx.on("counter:decrement", (e) => {
41
- e.stop();
42
- setValue((current) => current - 1);
43
- });
44
-
45
- // Events can be emitted from this context in a store.
46
- ctx.emit("otherEvent");
47
-
48
- ctx.onMount(() => {
49
- // Setup
50
- // This is called based on the context the store is attached to.
51
- // If Dolla, it's called when the app is mounted. If ViewContext, it's called when the view is mounted.
52
- });
53
- ctx.onUnmount(() => {
54
- // Cleanup
55
- });
56
-
57
- // Context variables will be accessible on the same context (e.g. the view this is attached to and below)
58
- ctx.get("context variable");
59
- ctx.set("context variable", "context variable value");
60
-
61
- // Stores don't have to return anything, but if they do it becomes accessible with `ctx.use(Store)`.
62
- return $value;
63
- }
64
-
65
- // Attach it to the app.
66
- Dolla.provide(CounterStore, 0);
67
-
68
- function ExampleView(props, ctx) {
69
- // ctx.use lets you access the return value
70
- // but the events will still be received and handled regardless
71
- const $count = ctx.use(Counter);
72
-
73
- return html`
74
- <button onclick=${() => this.emit("counter:decrement")}>-1</button>
75
- <span>${$count}</span>
76
- <button onclick=${() => this.emit("counter:increment")}>+1</button>
77
- `;
78
- }
79
- ```